如何在不使用Set的情况下计算ArrayList中的不同字符串?

时间:2016-03-14 08:58:01

标签: java arraylist

如何在不使用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();
}

6 个答案:

答案 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中为您提供不同字符串的数量。