如何在不使用Java库中的Set数据结构的情况下计算ArrayList
中不同字符串的数量?
我创建了两个ArrayLists,一个存储,一个空,并希望存储具有不同字符串的空列表。我做错了什么?
public void distinctCount (WordStream words) {
ArrayList<String> loaded = new ArrayList<String>();
ArrayList<String> empty = new ArrayList<String>();
int count = 0;
// Fill loaded with word stream
for(String i : words) {
loaded.add(i);
}
// Fill empty with loaded
// Catch collisions
for(int i = 0; i < loaded.size(); i++) {
if(loaded.get(i) != empty.get(i)) {
empty.add(loaded.get(i));
}
}
return empty.size();
}
答案 0 :(得分:3)
这是一个非常糟糕/慢的选择:
for(String s: loaded){
if(!empty.contains(s)){
empty.add(s);
}
}
或者如果你是Java 8粉丝:
empty = loaded.stream().distinct().collect(Collectors.toList())
答案 1 :(得分:1)
问题在于您只比较相应的元素。这意味着您将n th 元素与第二个arraylist中的n th 元素进行比较。
直接的解决方案是嵌套循环:对于第一个arraylist中的每个元素,循环遍历第二个数组列表中的所有元素,如果找不到匹配项 - 你知道它是独特的。该解决方案的复杂性为O(n 2 )。
当然,ArrayList
API中有许多有用的方法可以让您的生活更轻松。如果对其他数据结构没有限制,您也可以考虑使用Map
。
答案 2 :(得分:0)
使用map<String,Integer>
如果字符串存在,则获取该值并将其递增,如果该键没有值,则对该键添加1。
答案 3 :(得分:0)
使用Collections.sort() 如果所有列表项都实现了Comparable,则可以事先对列表进行排序,然后计算不等于的连续项。
private static int getUniqueCountUsingSort(List<String> list) {
if (list.size() < 2) { // obvious case.
return list.size();
}
List<String> listCopy = new ArrayList<>(list);
Collections.sort(listCopy);
int uniqueCount = 1;
for (int i = 1; i < listCopy.size(); i++) { // starts at 1.
// Compare with previous item in the sorted list.
if (!listCopy.get(i).equals(listCopy.get(i-1))) {
uniqueCount ++;
}
}
return uniqueCount;
}
此方法与Set方法具有相同的性能特征,因为Collections.sort()为O(n log(n))。
手动 你也可以简单地做到这一点,但速度较慢O(n ^ 2):
private static int getUniqueCountByHand(List<String> list) {
int uniqueCount = 0;
for (int i = 0; i < list.size(); i++) {
boolean isUnique = true;
// look if there is another entity before that is equal to this one.
for (int j = 0; j < i; j++) {
if (list.get(j).equals(list.get(i))) {
isUnique = false;
}
}
if (isUnique) {
uniqueCount ++;
}
}
return uniqueCount;
}
答案 4 :(得分:0)
loaded.stream().filter(w->!empty.contains(w)).forEach(w->empty.add(w));
根据评论中的建议。
List<String> empty = loaded.stream().distinct().collect(Collectors.toList());
答案 5 :(得分:0)
如果您不想使用Map
,请使用Set
。
Map<String, Integer> map=new HashMap<>();
int count=0;
for(String str:words) {
if(map.containsKey)
continue;
count++;
map.put(str,0);
}
return count;
Count会在Arraylist word
中为您提供不同字符串的数量。