使用集合比较字符串数组
我有两个字符串数组a,b。
String a [] = {"one","two","three"};
String b [] = {"one","Two","Three","four"};
我需要检查两个数组是否相同,且不区分大小写。 我知道,下面的代码非常适合区分大小写。
List <String> l1 = Arrays.asList(a);
List <String> l2 = Arrays.asList(b);
System.out.println(l2.containsAll(l1));
还有其他方法可以使用集合比较两个字符串数组(不区分大小写)吗?
I have two String arrays a,b.
String a [] = {"one","two","three"};
String b [] = {"one","Two","Three","four"};
I need to check whether both arrays are same or not , with case Insensitive .
I know , the following piece of code is perfect for case sensitive.
List <String> l1 = Arrays.asList(a);
List <String> l2 = Arrays.asList(b);
System.out.println(l2.containsAll(l1));
Is there any other way to compare two string array (case Insensitive ) using collection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
最后,我使用了 TreeSet 和不区分大小写的比较器。
示例:
谢谢大家..
Finally , I used TreeSet with case insensitive comparator.
Example :
Thanks Guys..
你不能只是循环它或使用某种 linq (抱歉,只是注意到这是 java,你不能使用 linq...?)
你可能想检查计数,因为我没有将其添加到代码,例如 l1.count > l2.count(在这种情况下,您可以通过列表中的元素数量知道它们是否相同)。在循环之前进行简单测试:
但与 JAVA 的逻辑相同...
Couldn't you just loop it or use some sort of linq (Sorry just noticed this was java you cant use linq...?)
You may want to check the count as I did not add that to the code, for instance l1.count > l2.count (in this case you know whether or not they are the same by the number of elements in the list). Simple test before even looping:
SAME LOGIC TO JAVA THOUGH...
您可以将 TreeMap 与案例一起使用-不敏感的比较器。
You could use a TreeMap with a case-insensitive comparator.
如果数组不包含重复项,以
O(N)
实现此目的的一种方法是使用表示规范形式的Set
数组中的字符串。像这样的事情:这是时间最优的。
您还可以对此技术进行变体以节省更多空间,例如,您可以为
arr1
构造规范集,然后根据元素从该集合中删除条目,而不是构造规范集并比较它们的arr2
。如果集合之后为空,并且您始终可以找到需要删除的内容,则这两个数组在规范上是相等的。如果您认为值得的话,您还可以进行简单的大小比较检查(即,如果两个数组经常没有相同数量的元素)。
如果数组中存在重复项,则
Set
方法将无法按原样工作。您需要一个多重集,您可以实现自己的,也可以使用 Google Collections。还有
O(N log N)
方法可以实现此目的,涉及对字符串进行排序。您可以对两个数组进行排序,然后进行简单的线性检查。必须使用不区分大小写的比较器,事实上它已经作为String.CASE_INSENSITIVE_ORDER
存在。即使数组包含重复项,最后一项技术仍然有效。它的执行时间复杂度为
O(N log N)
。它对作为参数传递的数组进行排序,因此如果原始状态很重要,您需要传递它们的clone()
。If the arrays don't contain duplicates, one way to do this in
O(N)
is to use aSet
that represents a canonical form of the strings in the array. Something like this:This is time-optimal.
You can also do variations on this technique to save more space, e.g. instead of constructing the canonical sets and comparing them, you can construct the canonical set for
arr1
, and then remove entries from that set according to elements ofarr2
. It the set is empty afterward, and you can always find what you need to remove, the two arrays are canonically equal.You can also do a simple size-comparison check if you think it's worth it (i.e. if often the two arrays don't even have the same number of elements).
If there are duplicates in the arrays, then the
Set
method will not work as is. You'd need a multiset, and you can either implement your own, or use Google Collections'.There are also
O(N log N)
ways to do this involving sorting the strings. You can sort both arrays and then do a simple linear check. A case-insensitive comparator must be used, and in fact it's already there asString.CASE_INSENSITIVE_ORDER
.This last technique works even if the arrays contain duplicates. It does it
O(N log N)
. It sorts the arrays passed as parameters, so if the original state is important, you want to pass theirclone()
instead.如果您想要自定义比较,请在嵌套循环中检查它。或者,如果您有大量数据,那么首先对数组进行排序可能会更便宜
check it in nested loops if you want custom comparison. or if you have large sets of data it might be cheaper to sort arrays first
您的样本数据已排序。如果现实中确实如此,那么您应该按照 Andrey 的说法进行操作,并在数组本身上使用嵌套循环,如果/当您找到一对不相等的条目时则中断。
如果不能保证它们被排序,我会将它们转储到 HashSet 中,然后您可以使用 java 的 Set containsAll 方法。
编辑:正如 Thomman 指出的, containsAll() 最终依赖于 equals()。因此,为了对您的问题请求进行不区分大小写的检查,您有两种选择:
1)在插入集合时将字符串大写或小写。考虑到这一点,我并不热衷于这种方法,因为您不仅会丢失重复的条目,而且还会折叠按大小写区分的条目。因此,这些列表看起来彼此相等:
2) 另一种选择是将字符串放入覆盖 equals() 的 Holder 对象中,以不区分大小写的方式进行比较。
Your sample data are sorted. If this is guaranteed to be the case in reality, you should do as Andrey says, and use nested loops on the arrays themselves, breaking if/when you find an inequal pair of entries.
If they're not guaranteed to be sorted, I'd dump each of them into a HashSet, and then you can use java's Set containsAll method.
Edit: As Thomman pointed out, containsAll() ultimately relies on equals(). So in order to get the case-insensitive checking your question requests, you have two choices:
1) Upcase or downcase the strings on insertion into the sets. On consideration, I'm not crazy about this method, since not only will you lose duplicate entries, but you'll also fold entries differentiated by case. And so these lists would look to be equal to each other:
2) The other choice is to put your strings into holder objects which override equals(), doing comparison in a case-insensitive way.
您可以先检查它们的长度是否相等。然后,您可以将
a
的项放入HashMap
中,然后检查b
并检查这些项是否存在。You could first check if their lengths are equal. Then you could put items of
a
inHashMap
and go overb
and check if the items are there.使用一个 for 循环 -
Using one for loop -