2015-05-05 4 views

risposta

26

Il codice dovrebbe essere ripetuto su tutti gli elementi. Se si desidera assicurarsi che non vi siano duplicati metodo semplice come

public static <T> boolean containsUnique(List<T> list){ 
    Set<T> set = new HashSet<>(); 

    for (T t: list){ 
     if (!set.add(t)) 
      return false; 
    } 

    return true; 
} 

sarebbe più efficiente.

Questo metodo potrebbe anche essere riscritta come (supponendo flussi non paralleli e ambiente thread-safe)

public static <T> boolean containsUnique(List<T> list){ 
    Set<T> set = new HashSet<>(); 
    return list.stream().allMatch(t -> set.add(t)); 
} 

o come @Holger menzionato in commento

public static <T> boolean containsUnique(List<T> list){ 
    return list.stream().allMatch(new HashSet<>()::add); 
} 
+18

Questo può essere anche un one-liner: 'return list.stream(). AllMatch (new HashSet <>() :: add);' – Holger

+2

@Holger Wow, non ho mai pensato a questo. Ogni giorno imparo qualcosa di nuovo :) Grazie! – Pshemo

+6

Sembra un po 'pericoloso usare un predicato con effetti collaterali qui. –

1

introduttiva questa classe come StreamTool, ma penso che ci deve essere un modo ancora migliore con riduzione o simile:

public class StreamTool { 

    /** 
    * Whether stream records are unique in that stream. 
    * @param <T> Type of records 
    * @param records 
    * @return true if there are no duplicates, false otherwise 
    */ 
    public static <T> boolean isUnique(Stream<T> records) { 
     return records.allMatch(new HashSet<>()::add); 
    } 
} 
7

Ho utilizzato quanto segue:
1. return list.size() == new HashSet<>(list).size();.

io non sono sicuro di come si paragona a:
2. return list.size() == list.stream().distinct().count();
e
3. return list.stream().sequential().allMatch(new HashSet<>()::add);
in termini di prestazioni.

L'ultimo (n. 3) ha la possibilità di gestire non solo raccolte (ad esempio elenchi), ma anche flussi (senza raccoglierli esplicitamente).

0

È possibile utilizzare il collettore di conteggio.

Stream.of(1, 3, 4, 6, 7, 5, 6) 
      .collect(Collectors.groupingBy(
        Function.identity(), Collectors.counting())) 
      .entrySet().stream().anyMatch(e -> e.getValue() > 1)