【问题标题】:Which approach is better comparing a value in method check or checking if it exists in an array?哪种方法更好地比较方法检查中的值或检查它是否存在于数组中?
【发布时间】:2019-11-26 07:08:15
【问题描述】:

假设我有一个场景,当它满足条件时,需要完成某些很棒的任务。

public class Check101 {

public static boolean validColor(String color) {
    return color.equals("RED")
            || color.equals("BLUE")
            || color.equals("GREEN");
}
public static List<String> validColorList= new ArrayList<String>(Arrays.asList("RED","GREEN","BLUE"));

public static void main(String[] args) {
    String color = "RED";
    if (validColor(color)) {
        //do awesome work
    }
    if(validColorList.contains(color)){
        //do awesome work
    }
}

}

现在看起来还不错,因为它只有原色, 如果有效颜色增加到(i)100 和(ii)1600 万颜色会怎样。 那么哪个是最好的方法呢? 请注意,我受限于不使用 Set/HashMap 或 O(1) 可搜索容器,并且只被要求回答这个奇怪的场景。

【问题讨论】:

  • 不使用Set的原因是什么?
  • 我奇怪的导师问了我这个问题,他允许我的唯一其他方法是枚举而不是列表。
  • 这两种方法都不适用于 1600 万色。
  • 我同意 1600 万色的观点,但第一点呢?

标签: java arrays arraylist enums time-complexity


【解决方案1】:

当您使用List 时,没有理由将通过Arrays.asList("RED","GREEN","BLUE") 生成的列表复制到另一个ArrayList。你可以简单地声明它

public static List<String> validColorList = Arrays.asList("RED","GREEN","BLUE");

当您不允许使用 Set 时,两种方法都会执行线性搜索,这在性能方面同样很糟糕。但是列表方法更易于维护,因为添加另一个值只需要添加该值(到初始化器列表中),而不是添加另一个 if 语句。

这可能会扩展到 100 个值,而即使是线性搜索的性能缺陷也可能与 100 个值无关,只要您不经常执行查找,例如在一个紧密的循环中。

但是,这两种方法都不能用于 16M 色。这甚至不是不切实际或具有灾难性的性能,它只是不可能。 Java 方法的最大代码大小为 65536 字节,这适用于持有if 语句的普通方法或构造List 的类初始值设定项。每个表达式或语句都需要几个字节,因此这两种方法都将在几千个值的阈值处停止工作。即使将代码拆分为多个方法,单个类中可以定义的字符串常量也少于 65535 个。

要管理更多的值,您应该将名称列表作为资源嵌入到您的代码中,并使用类似的东西,例如

public static final List<String> validColorList;
static {
    try {
        validColorList = Files.readAllLines(
            Paths.get(MyClass.class.getResource("color-list").toURI()));
    } catch(IOException|URISyntaxException ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

但是当我们进行此类更改时,没有理由对其他强烈推荐的更改犹豫不决:

public static final Set<String> validColorList;
static {
    try {
        validColorList = new HashSet<>(Files.readAllLines(
            Paths.get(SO59045501.class.getResource("color-list").toURI())));
    } catch(IOException|URISyntaxException ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

链接if 语句的方法没有等效的方法。

【讨论】:

  • 这是一个非常有意义和描述性的答案。谢谢:)
【解决方案2】:

这取决于你认为什么“更好”。

  • 当与一个值比较时,您具有直接访问的优势,而使用数组时,您有迭代数组的开销。因此,值比较方法具有较小的性能优势。
  • 另一方面,使用数组是一种更通用的方法,可以轻松增强(从文件中读取数组或从 Web 中提取数组)。此外,它更适合依赖注入(将逻辑保留在类中,同时允许外部源的值),更易于测试。

【讨论】:

  • 感谢您的回答,对于主要的 3 种颜色,它几乎不重要,但是与大约 100 多个值(不包括 16m 的情况)相比,方法值比较是否比数组循环具有性能优势?我也同意代码易于维护的观点。
猜你喜欢
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 2019-10-23
  • 2014-06-01
  • 2012-06-24
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多