在列表中查找重复的字符串并使其唯一

时间:2016-11-26 08:24:33

标签: java list duplicates unique

我的ArrayList有重复的字符串值,并希望通过附加计数使重复项唯一。

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("b");
    list.add("c");
    list.add("a");
    list.add("a");
    list.add("a");

    HashSet<String> set = new HashSet<String>();
    List<String> duplicateList = new ArrayList<String>();

    for (String item : list) {
        // If String is not in set, add it to the list and the set.
        if (!set.contains(item)) {              
            set.add(item);
        } else {
            duplicateList.add(item);
        }
    }

    for (String element : duplicateList) {
        System.out.println(element);
    }
}

有没有办法让列表像:

a
b
c
d
b1
c1
a1
a2
a3

5 个答案:

答案 0 :(得分:10)

假设您使用 Java 8 ,如果您想获得List的每个值的重复总量,那么感谢Stream API通过按值分组,然后计算每个值的出现次数:

Map<String, Long> counter = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counter);

<强>输出:

{a=4, b=2, c=2, d=1}

如果您想通过在原始String末尾添加计数器来防止重复,可以使用LinkedHashSet来保留值&#39;按照 Elliott Frisch 的提议进行排序。

Elliott Frisch 的方法略有不同:

List<String> list = Arrays.asList("a", "b", "c", "d", "b", "c", "a", "a", "a");
Set<String> set = new LinkedHashSet<>();
for (String str : list) {
    String value = str;
    // Iterate as long as you can't add the value indicating that we have
    // already the value in the set
    for (int i = 1; !set.add(value); i++) {
        value = str + i;
    }
}
System.out.println(set);

<强>输出:

[a, b, c, d, b1, c1, a1, a2, a3]

答案 1 :(得分:9)

看起来你有正确的想法。您只需要使用Map并实际计算遇到的字符串,而不是仅仅注意到它们遇到过:

Map<String, Integer> counter = new HashMap<>();
List<String> duplicateList = new ArrayList<>();

for (String item : list) {

    // If String is not in set, add it to the list and the set, and 
    // note this is the first time it's encountered
    if (!counter.containsKey(item)) {
        duplicateList.add(item);
        counter.put(item, 1);
    } else {
        Integer count = counter.get(item);
        duplicateList.add(item + count);
        item.put(item, count + 1);
    }
}

答案 2 :(得分:4)

您可以使用LinkedHashSet,然后使用Arrays.asList(T...)初始化List。首先,检查集合是否包含list中的元素。如果是,则迭代值,直到找到尚未显示​​的值。像,

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d", 
        "b", "c", "a", "a", "a"));
Set<String> mySet = new LinkedHashSet<>();
for (String str : list) {
    if (mySet.contains(str)) {
        int i = 1;
        while (mySet.contains(str + i)) {
            i++;
        }
        str = str + i;
    }
    mySet.add(str);
}
System.out.println(mySet);

哪些输出(根据要求)

[a, b, c, d, b1, c1, a1, a2, a3]

答案 3 :(得分:1)

如果要更改现有列表:

public static void main(String ... args) {
    List<String> names = Arrays.asList("a", "b", "c", "d", 
            "b", "c", "a", "a", "a");

    updateDuplicates(names);

    System.out.println(names);

}

private static void updateDuplicates(List<String> names) {
    ListIterator<String> litr = names.listIterator();
    Map<String, Integer> occurenceCounter = new HashMap<>();
    while(litr.hasNext()) {
        String currentName = litr.next();
        if(!occurenceCounter.containsKey(currentName)) {
            occurenceCounter.put(currentName,0);
        }else {
            Integer currentCount = occurenceCounter.get(currentName);
            occurenceCounter.put(currentName, ++currentCount);
            litr.set(currentName + currentCount);
        }
    }

}

答案 4 :(得分:0)

您可以将Java与哈希 O(n)

一起使用

此处l是输入列表

public static List getUniqueList(List<String> l){
    HashMap<String,Integer> hm=new HashMap<String,Integer>();
    for(int i=0;i<l.size();i++) {
        String key=l.get(i);
        if(hm.containsKey(key)) {
            l.set(i, key+hm.get(key));
            hm.put(key,hm.get(key)+1);
        }else { 
            //newl.add(key);
            hm.put(key,1);
        }
    }
return l;
}