2016-03-28 10 views
0

Ich habe den folgenden Code (mit einigen Beispieldaten), und wünschte zu prüfen, ob es eine bessere oder performante Art und Weise ist jedes Element der Liste der Karte auf die nachfolgende zu vergleichen:Wie vergleicht man Elemente einer Liste mit Elementen einer Karte in Java?

import java.util.*; 

public class CompareElements { 

private static List<Map<String, String>> sample = new ArrayList<>(0); 
private static int MIN = 0; 
private static int MAX = 10; 

static { 
    populateListOfMaps(); 
} 

/* 
* This is the main part of the question, rest is just to generate test data.. 
*/ 
public static void main(String[] args){ 
    // Can we simplify this part using lambda's or any library? 
    for (int i = 0; i < sample.size() -1; i++) { 
     for (int j = i+1; j < sample.size(); j++) { 
      Map<String, String> referenceMap = sample.get(i); 
      Map<String, String> candideMap = sample.get(j); 
      if(referenceMap.get("key").equalsIgnoreCase(candideMap.get("key"))){ 
       System.out.println("Equal : " + i + " || " + referenceMap.get("key") + " and "+ j + " || " + candideMap.get("key") + " are pairs"); 
      } else { 
       System.out.println("Not equal : " + i + " || " + referenceMap.get("key") + " and "+ j + " || " + candideMap.get("key") + " are pairs"); 
      } 
     } 
    } 
} 

private static void populateListOfMaps(){ 
    if(sample.size() <= 10){ 
     Map<String, String> someMap = new HashMap<>(0); 
     someMap.put("key", "value" + randInt(MIN, MAX)); 
     sample.add(someMap); 
     populateListOfMaps(); 
    } 
} 

public static int randInt(int min, int max) { 
    Random rand = new Random(); 
    int randomNum = rand.nextInt((max - min) + 1) + min; 
    return randomNum; 
} 

}

Meine Anforderung ist, jedes Element der Liste der Karten zu vergleichen und dann auf Gleichheit zu prüfen, um doppelte zu entfernen, das ist ein einfacher Teil, aber jede Karte in meiner Echtzeitanwendung hat 2 Schlüsselwerte (aber beide sind String .. nein benutzerdefiniertes POJO-Objekt).

Der obige Code funktioniert, aber ich möchte diesen prägnanteren und leistungsfähigeren Code machen.

Können wir Lambdas oder Streams verwenden?

+0

Alle Hinweise. . meint? –

+0

"Echtzeit" bedeutet; mit einer konsistenten Latenz. "echte Welt" bedeutet; in der realen Welt, dh. nicht theoretisch. –

+2

"Der obige Code funktioniert, aber ich möchte diesen prägnanteren und performanteren Code erstellen." - Ich denke, dass Ihre Frage in http://codereview.stackexchange.com/ gepostet werden sollte, da sie off-topic für StackOverflow ist. –

Antwort

0

Da Sie Daten von MongoDB erhalten, nehme ich an, dass Sie keine Kontrolle über das Schema haben, also ist die Verwendung eines POJO keine einfache Option. (Es kann mit generierten Code getan werden, aber Sie wollen wahrscheinlich nicht dorthin gehen)

Was können Sie tun groupingBy wird mit dieser O(n^2) Schleifen in O(n)

public static void main(String... args) { 
    List<Map<String, String>> sample = populateListOfMaps(); 
    sample.stream() 
      .collect(Collectors.groupingBy(m -> m.get("key"))) 
      .forEach((key, list) -> System.out.println(key + " : " + list)); 
} 

private static List<Map<String, String>> populateListOfMaps() { 
    Random rand = new Random(); 
    return IntStream.range(0, 10) 
      .mapToObj(i -> { 
       Map<String, String> someMap = new HashMap<>(2); 
       someMap.put("key", "value-" + rand.nextInt(10)); 
       return someMap; 
      }) 
      .collect(Collectors.toList()); 
} 

dieser Druck die alles wird sich ändern Einträge, die den gleichen "Schlüssel" -Wert haben mit O(n) zeitlicher Komplexität. z.B.

value-9 : [{key=value-9}] 
value-8 : [{key=value-8}, {key=value-8}, {key=value-8}] 
value-5 : [{key=value-5}] 
value-7 : [{key=value-7}, {key=value-7}] 
value-1 : [{key=value-1}] 
value-0 : [{key=value-0}] 
value-2 : [{key=value-2}] 
0

Ich bin nicht wirklich sicher, was Ihre genauen Anforderungen sind so Ihre Frage ein Teil zu einer Zeit, in Angriff zu nehmen:

prüfen, ob es eine bessere oder performante Art und Weise ist jedes Element des vergleichen Liste der Karte zum folgenden:

Wie wäre es mit KeySets?

Set<String> s1 = new HashSet<String>(referenceMap.values()); 
Set<String> s2 = new HashSet<String>(candideMap.values()); 

// Get intersection of values 
s1.retainAll(s2); 

// You can also get corresponding keys for each value later 

Dies sollte Ihre Komplexität vor O(n^2) zu O(n)

jede Karte in meiner Echtzeit-Anwendung verfügt über 2 Tasten-Werte (aber beide sind String .. kein benutzerdefiniertes POJO Objekt) reduzieren.

Nicht sicher, was Sie in Echtzeit meinen. Ändern sich die Karten in Echtzeit? Weder deine Lösung noch meine wäre threadsicher.

Meinst du 2 Schlüssel-Werte für jeden Eintrag? Wenn Sie 2 Werte für jeden Schlüssel meinen, würden Sie wahrscheinlich die hashcode(), equals() überschreiben und Ihr Code sollte funktionieren.

Lassen Sie mich wissen, wenn ich Ihre Frage missverstanden

Verwandte Themen