我有一张地图:
Map<String, String> abc = new HashMap<>();
"key 1":"价值1",
"key 2":"价值2"
以及一个数组:
String[] options= {"value1", "value2", "value3"}
我如下创建这个数组(我使用以下方法做一些与我在这里提出的问题无关的事情):
public String[] getOptions() {
List<String> optionsList = getOptionsFromAMethod(WebElementA);
String[] options = new String[optionsList.size()];
options = optionsList.toArray(options);
return options;
}
验证 String[] 是否包含 Map 中的每个值的最佳方法是什么?
我正在考虑这样做:
for (Object value : abc.values()) {
Arrays.asList(options).contains(value);
}
我建议使用流:
final List<String> optionsList = Arrays.asList(options);
abc.values().stream().allMatch(optionsList::contains);
可以使用https://docs . Oracle . com/javase/7/docs/API/Java/util/list . html # contains all(Java . util . collection)
Arrays.asList("value1", "value2", "value3").containsAll(abc.values())
您当前的方法创建了一个<code>ArrayList</code>(来自<code>java.util.Arrays</code>,不要与<code>java.util</code>中的常规ArrayList混淆)来包装给定的数组。
然后,对于map的每个值,您调用ArrayList#包含
方法。然而,这种方法非常慢。它遍历整个列表以搜索某些内容。
因此,您当前的方法会产生O(n^2)
,这不能很好地扩展。
我们可以通过使用专为快速包含
查询而设计的数据结构(即 HashSet
)来做得更好。
因此,我们不会将所有值放入ArrayList
,而是将它们放入HashSet
,其包含
方法速度很快:
boolean doesContainAll = true;
HashSet<String> valuesFromArray = new HashSet<>(Arrays.asList(options));
for (String value : abc.values()) {
if (!valuesFromArray.contains(value)) {
doesContainAll = false;
break;
}
}
// doesContainAll now is correctly set to 'true' or 'false'
该代码现在在O(n)
中工作,这要好得多,而且在复杂性方面也是最佳的。
当然你可以通过恒定因素进一步优化加速。例如,你可以先检查大小,如果options.length
大于abc.values()。大小()
那么你可以直接返回false
。
您还可以使用Java 8和Stream
s来简化上述代码,其结果和幕后过程是相同的:
HashSet<String> valuesFromArray = new HashSet<>(Arrays.asList(options));
boolean doesContainAll = abc.values().stream()
.allMatch(valuesFromArray::contains);
让我们仔细看看< code > Java . util . arrays . ArrayList 。你可以在这里找到它的代码。
以下是包含
方法的代码:
public boolean contains(Object o) {
return indexOf(o) != -1;
}
让我们看看indexOf
是如何实现的:
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
事实上,在所有情况下,该方法都将从左到右遍历源数组以查找对象。无论对象是否包含,都没有能够直接访问信息的花哨方法,它在O(n)
中运行,而不是在O(1)
中运行。
如果您的任何一个数据可能包含重复项,并且您计划单独计数它们,那么您将需要一种稍微不同的方法,因为包含
不会为重复项的数量而烦恼。
为此,您可以先将abc.values()
收集到List
中。然后,每次检查一个元素时,您都将从List
中删除匹配的元素。
或者,您可以设置HashMap
如何检查数组中的所有元素是否相同? 这是我想到的唯一解决办法。我想知道有没有有效的?
我实际上有两种类型的数据: 我想用Hamcrest在我的身体响应中测试我的放心请求后,b(元素接收)是否包含来自a的一个或多个元素(
问题内容: 如何测试字符串以查看其是否包含数组中的任何字符串? 而不是使用 问题答案: 编辑:这是使用Java 8流API的更新。如此清洁。仍然可以与正则表达式结合使用。 另外,如果我们将输入类型更改为List而不是数组,则可以使用。 如果希望返回匹配的字符串,也可以使用。 原始的过时的答案: 这是(VERY BASIC)静态方法。请注意,在比较字符串上区分大小写。一个原始的,使其不区分大小写的办
问题内容: 找出JavaScript数组是否包含值的最简洁,最有效的方法是什么? 这是我知道的唯一方法: 有没有更好,更简洁的方法来实现这一目标? 这与Stack Overflow问题密切相关。在JavaScript数组中查找项目的最佳方法?解决使用数组查找对象的问题indexOf。 问题答案: 现代的浏览器,这不正是这一点,得到广泛支持的人,除IE: 你也可以使用,它不太直接,但对于过时的浏览器
问题内容: 找出JavaScript数组是否包含值的最简洁,最有效的方法是什么? 这是我知道的唯一方法: 有没有更好,更简洁的方法来实现这一目标? 这与Stack Overflow问题密切相关。 在JavaScript数组中查找项目的最佳方法?解决使用数组查找对象的问题。 问题答案: 现代的浏览器,这不正是这一点,得到广泛支持的人,除IE: 你也可以使用,它不太直接,但对于过时的浏览器不需要使用。
问题内容: 如何测试一个列表是否包含另一个列表(即它是一个连续的子序列)。假设有一个名为contains的函数: 编辑: 问题答案: 这是我的版本: 正如安德鲁·贾菲(Andrew Jaffe)在他的评论中指出的那样,它返回一个元组(start,end + 1),因为我认为这更像pythonic。它不对任何子列表进行切片,因此应该相当有效。 新手感兴趣的一点是,它使用了for语句上的else子句-