2015-08-11 11 views
11

Ho nested LinkedList che contiene alcuni elementi. Voglio rimuovere Duplicate InnerListList da Outter LinkedList. L'ordine dell'elemento non importa. [Cat. , Mouse, Dog] è uguale a [Mouse, Cat, Dog] e voglio rimuovere 1 di loro. esempio:Rimuovi elementi duplicati da una lista collegata, in cui gli elementi di raccolta nidificati possono essere in qualsiasi ordine

supponiamo

[[Cat,Mouse,Dog],[Dog,Mouse,Cat],[Dog,Horse,Cat],[Dog,Tiger,Lion]] 

poi voglio output come questo

[[Cat,Mouse,Dog],[Dog,Horse,Cat],[Dog,Tiger,Lion]] 

ho provato. ma voglio soluzione ottimale ...... Il mio codice è il seguente

for (int iBoardListCnt = 0; this.roomCombinationsMasterList != null && iBoardListCnt < this.roomCombinationsMasterList.size(); iBoardListCnt++) { 

     LinkedList<Board> alRoomCombinationList = new LinkedList<>(); 
     alRoomCombinationList = this.roomCombinationsMasterList.get(iBoardListCnt); 
     ArrayList<String> alTemp = new ArrayList(); 
     for (int icount = 0; icount < alRoomCombinationList.size(); icount++) { 
      alTemp.add((alRoomCombinationList.get(icount).getRoomDescription() + alRoomCombinationList.get(icount).getDescription()).toString()); 
     } 
     roomCombinationsMasterList.remove(iBoardListCnt); 



     Collections.sort(alTemp, new Comparator<String>() { 
      @Override 
      public int compare(String s1, String s2) { 
       return s1.compareToIgnoreCase(s2); 
      } 
     }); 

     Iterator<LinkedList<Board>> iterator = roomCombinationsMasterList.iterator(); 
     while (iterator.hasNext()) { 

      ArrayList<String> alTemp1 = new ArrayList<>(); 
      for (Board data : iterator.next()) { 
       alTemp1.add((data.getRoomDescription() + data.getDescription()).toString()); 

      } 
      Collections.sort(alTemp1, new Comparator<String>() { 
       @Override 
       public int compare(String s1, String s2) { 
        return s1.compareToIgnoreCase(s2); 
       } 
      }); 

      if (alTemp.equals(alTemp1)) { 
       iterator.remove(); 
       continue; 
      } 

     } 

     roomCombinationsMasterList.add(iBoardListCnt, alRoomCombinationList); 

    } 

In questo codice ho preso elemento Pugno da nidificati LinkedList. memorizzato nella LinkedList temporanea ho rimosso quell'elemento dal main arraylist.Ora ho l'elemento successivo da LinkedList memorizzato in 2nd LinkList temporanea. Ordina sia LinkedList usando Comparator E usando il metodo equals() confronta questi due LinkedList.If entrambi sono identici, quindi rimuovi 1 di essi usando Iterator. per favore dammi una soluzione ottimale su di esso.

+0

utilizza uno Set of Imposta un'opzione per te?Perché dovrebbero fare quello che vuoi. – Flown

+0

No ... non posso usare Set collection ... perché i miei dati sono in forma di lista collegata di linkedlist –

risposta

4

Esistono diversi modi per rimuovere elementi duplicati dall'elenco. La soluzione "ottimale" di cui hai bisogno richiederà l'utilizzo di una struttura dati appropriata, ottimizzata per l'operazione contains. Nel tuo caso sarà HashSet.

L'idea è che mentre attraversi la tua collezione originale nello stesso tempo mantieni il set di elementi attraversati e controlli se l'elemento corrente era già attraversato. Questo approccio modifica la tua collezione originale in atto.

List<List<String>> input = new LinkedList<List<String>>(Arrays.asList(
      Arrays.asList("Cat", "Mouse", "Dog"), 
      Arrays.asList("Dog", "Mouse", "Cat"), 
      Arrays.asList("Dog", "Horse", "Cat"), 
      Arrays.asList("Dog", "Tiger", "Lion"))); 

    Set<Set<String>> distinctElements = new HashSet<Set<String>>(); 

    for (Iterator<List<String>> iterator = input.iterator(); iterator.hasNext();) { 
     List<String> element = iterator.next(); 
     HashSet<String> elementAsSet = new HashSet<String>(element); 
     if (!distinctElements.contains(elementAsSet)) { 
      distinctElements.add(elementAsSet); 
     } else { 
      iterator.remove(); 
     } 
    } 

    System.out.println(input); 

Seconda opzione verrà trasformando la vostra lista originale delle liste in LinkedHashSet<LinkedHashSet<String>>. LinkedHashSet si comporta come uno Set e List allo stesso tempo (in realtà, ha entrambe queste strutture dati sotto il cofano). Quindi elimina i duplicati preservando l'ordine degli elementi, proprio come è necessario. Probabilmente non è un'opzione per te, come hai detto che devi conservare il tuo tipo di collezione, ma comunque, è una buona (e breve) opzione degna di considerazione.

LinkedHashSet<LinkedHashSet<String>> results = new LinkedHashSet<LinkedHashSet<String>>(); 
    for (List<String> strings : input) { 
     results.add(new LinkedHashSet<>(strings)); 
    } 
    System.out.println(results); 

E, infine, l'one-liner per Java 8:

LinkedList<LinkedList<String>> results = input.stream().map(LinkedHashSet::new).distinct() 
     .map(LinkedList::new).collect(Collectors.toCollection(() -> new LinkedList<LinkedList<String>>())); 

O è la versione più breve se non vi interessa circa il tipo di collezione restituita:

List<List<String>> results = input.stream().map(LinkedHashSet::new).distinct() 
     .map(LinkedList::new).collect(Collectors.toList()); 
+0

Grazie, credo che funzionerà bene nel mio scenario ... attraversare e rimuovere allo stesso tempo ridurrà il tempo consumato per l'iterazione. –

+0

@kalpeshkalambe tecnicamente hai ragione sul tempo ridotto, ma la differenza sarà trascurabile rispetto al tempo consumato creando 'Set' per il controllo dei duplicati. Giusto per fartelo sapere. – Aivean

2
import java.util.*; 

import static me.test.Test.Animal.*; 
public class Test { 

    public static enum Animal { 
     Dog,Tiger,Lion,Horse,Cat,Mouse 
    } 

    public static void main (String[] args) { 
     List<Animal> list1 = new LinkedList<>(Arrays.asList(Cat,Mouse,Dog)); 
     List<Animal> list2 = new LinkedList<>(Arrays.asList(Dog,Mouse,Cat)); 
     List<Animal> list3 = new LinkedList<>(Arrays.asList(Dog,Horse,Cat)); 
     List<Animal> list4 = new LinkedList<>(Arrays.asList(Dog,Tiger,Lion)); 

     List<List<Animal>> list = new LinkedList<>(Arrays.asList(list1, list2, list3, list4)); 

     Set<List<Animal>> sorted = new LinkedHashSet<>(); 

     for (List<Animal> animals : list) { 
      List<Animal> arList = new ArrayList<>(animals); 
      Collections.sort(arList); 
      sorted.add(new LinkedList<>(arList)); 
     } 

     for (List<Animal> animals : sorted) { 
      System.out.println(animals); 
     } 
    } 
} 

algoritmo: liste sorta individuali, in modo che possiamo confrontare. liste come [gatto, cane] e [cane, gatto] sono uguali, ma uguali restituirebbero false. ora, usa semplicemente HashSet. Il metodo hashCode() per esso eseguirà l'iterazione dei singoli elementi su ogni aggiunta per generare l'hash, che può quindi essere utilizzato per confrontare gli elenchi. ho usato LinkedHashSet, in modo che sia possibile ripristinare l'ordine originale.

+0

grazie per la soluzione ... posso usare enum per bean ... dato che i miei dati provengono dai fagioli –

1

Prova questo ho creato una soluzione ottimizzata con il tempo minimo richiesto.

public class UniqueLinkedList { 

    public static void main(String[] args) { 
     List<String> list1 = new LinkedList<>(Arrays.asList("Cat","Mouse","Dog")); 
     List<String> list2 = new LinkedList<>(Arrays.asList("Dog","Mouse","Cat")); 
     List<String> list3 = new LinkedList<>(Arrays.asList("Dog","Horse","Cat")); 
     List<String> list4 = new LinkedList<>(Arrays.asList("Dog","Tiger","Lion")); 
     List<List<String>> list = new LinkedList<>(Arrays.asList(list1, list2, list3, list4)); 
     boolean flag = false; 
     boolean matchFlag = true; 
     for(int i = 0; i < list.size(); i++){ 
      for(int j = i+1; j < list.size(); j++){ 
       if(list.get(i).size() == list.get(j).size()){ 
        matchFlag = true; 
        for(String str : list.get(i)){ 
         flag = false; 
         for(String string : list.get(j)){ 
          if(str.equals(string)){ 
           flag = true; 
          } 
         } 
         if(flag == false){ 
          matchFlag = false; 
          break; 
         } 
        } 
        if(matchFlag){ 
         list.remove(j); 
         j--; 
        } 
       } 
      } 
     } 
     System.out.println(list.size()); 
     for(int i = 0; i < list.size(); i++){ 
      System.out.println(list.get(i)); 
     } 
    } 
} 
+2

Hai dimenticato di includi 'j -' quando stai facendo 'list.remove (j);' –

+0

Grazie a Naman Gala per aver detto l'errore. –