2016-11-26 12 views
8

Mam ArrayList z duplikatowymi wartościami ciągów i chcę, aby duplikaty były unikalne poprzez dołączanie liczby.Znajdź zduplikowane ciągi na liście i uczyń je unikalnymi.

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); 
    } 
} 

Czy istnieje jakiś sposób, aby zrobić listę takich jak:

a 
b 
c 
d 
b1 
c1 
a1 
a2 
a3 
+2

Czemu przechowywania danych w listy tablicy? Na tym przede wszystkim należy zacząć. –

+0

@ThomasJunk. Chcę listę z duplikatami wartości. Czy jest jakiś sposób? – user2196474

Odpowiedz

9

Wydaje się, że masz rację. Wystarczy użyć Map i faktycznie policzyć napotkane ciągi zamiast po prostu zauważyć, że były one spotykane:

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); 
    } 
} 
7

Zakładając, że używasz Java 8, jeśli chcesz uzyskać całkowitą ilość powtórzeń każdego wartość swojego List, można to zrobić dzięki Stream API grupując wartościami następnie liczenia wystąpień każdej wartości jako następny:

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

wyjściowa:

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

Jeśli chcesz uniknąć duplikatów dodając licznika na końcu oryginalnego String, można użyć LinkedHashSet zachować kolejność wartości, jak proponowane przez Elliott Frisch.

Nieco inne podejście od Elliott Frisch jest jedna:

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); 

wyjściowa:

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

Możecie użyć LinkedHashSet, i można użyć Arrays.asList(T...) zainicjować swoją List . Najpierw sprawdź, czy zestaw zawiera element z list. Jeśli tak, to iterują wartości, aż znajdziesz taki, który jeszcze się nie pojawia. Coś podobnego,

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); 

które wyjścia (na żądanie)

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

@NicolasFilotto To 'Lista' nie jest zmienne. Nie ma pewności, czy ma to znaczenie w przypadku OP. –

Powiązane problemy