2016-04-14 7 views
1

Ich versuche, ein kartesisches Produkt von List in Java mit diesem Code zu generieren:kartesischer der Liste in Java

private static List<List<String>> getCartesian(List<List<String>> initialList) 
{ 
    List<List<String>> result = new ArrayList<List<String>>(); 
    result.add(new ArrayList<String>()); 
    for (List<String> first : initialList) 
    { 
     List<List<String>> temporaryList = new ArrayList<List<String>>(); 
     for (List<String> second : result) 
     { 
      for (String word : first) 
      { 
       List<String> tmp2 = new ArrayList<String>(second); 
       tmp2.add(word); 
       temporaryList.add(tmp2); 
      } 
     } 
     result = temporaryList; 
    } 
    return result; 
} 

Ich erhalte die folgende Fehlermeldung, wenn ich große Listen mit:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

Was kann ich tun, damit Big Data funktioniert?

+1

Siehe JVM-Option -Xmx. –

+2

Müssen Sie alle diese Listen gleichzeitig im Speicher haben? Was machst du mit dem Produkt, wenn du es gemacht hast? – khelwood

+0

Führen Sie Java mit der Befehlszeilenoption -Xmx aus, mit der die maximale Größe des Heapspeichers festgelegt wird. Standard ist 512M ich denke, also bewusst sein: Sie verwenden eine Menge Speicher für diese Funktion ... – Exceptyon

Antwort

0

Sie sollten versuchen, die Verwendung von ArrayList für solche Dinge zu vermeiden. Alle Informationen, die zum Erzeugen des Ergebnisses benötigt werden, sind in der ursprünglichen List<List<String>> enthalten, so dass nicht alle Antworten gleichzeitig im Speicher vorhanden sein müssen.

Der folgende Code erzeugt eine Liste gleich getCartesian, aber es speichert nicht alles in einem großen ArrayList. Stattdessen erstellt es eine Kopie aller ursprünglichen Listen und berechnet eine einzelne Antwort, wenn sie angefordert wird.

public static List<List<String>> getCartesian2(List<List<String>> lists) { 
    long size = 1; 
    final List<List<String>> copy = new ArrayList<List<String>>(); 
    for (List<String> list : lists) { 
     size *= list.size(); 
     if (size > Integer.MAX_VALUE) 
      throw new IllegalArgumentException(); 
     copy.add(new ArrayList<String>(list)); 
    } 
    final int fSize = (int) size; 
    return new AbstractList<List<String>>() { 
     @Override 
     public int size() { 
      return fSize; 
     } 
     @Override 
     public List<String> get(int i) { 
      if (i < 0 || i >= fSize) 
       throw new IndexOutOfBoundsException(); 
      String[] arr = new String[copy.size()]; 
      for (int j = copy.size() - 1; j >= 0; j--) { 
       List<String> list = copy.get(j); 
       arr[j] = list.get(i % list.size()); 
       i /= list.size(); 
      } 
      return Arrays.asList(arr); 
     } 
    }; 
}