哪种方法比较方法检查中的值或检查它是否存在于数组中更好?



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

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( 可搜索容器,并且被要求只回答这个奇怪的场景。

当你使用一个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语句的方法没有等效项。

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

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

最新更新