2016-04-02 18 views
0

dies sieht nicht wie ein Duplikat zu bestehenden Schnittpunkt/Union Fragen (ich kann falsch).Finden Sie den Unterschied zwischen zwei Arrays

Ich habe zwei Arraylisten, die eine Klasse enthält, die einen Wert enthält, zum Beispiel

class A { 
    private int value; 

    public int getValue() { 
     return value; 
    } 
} 

Und meine Listen sind

ArrayList<A> first, second; 

ich zwei Indizes von first und second, finden möchten die Erste Indizes sind Punkte auf Positionen in first, die die entsprechenden Werte nur in first, aber nicht in second, und die anderen Indizes sind in second, dass die Respe Werte nur in second, aber nicht in first.

Zum Beispiel (lesen Sie von der Mitte Reihen, wo die Daten hat):

hit     * * 
index of first 0 1 2 3 
---------------------------------- 
first.value  1 3 5 7 
second.value  1 2 4 6 7 8 
---------------------------------- 
index of second 0 1 2 3 4 5 
hit    * * * * 

Ich möchte zwei Indizes von 1 2 und 1 2 3 5.

Hinweis:

  1. ich lieber nicht 3rd-Party-Bibliotheken
  2. Werte sind ganze Zahlen und sortiert, und ich die Rückkehr muss auch, um verwenden.
  3. Längen von first und second sind unsicher - jeder kann länger sein als der andere.

Danke.

PS: Jeder braucht mehr Details, das ist eine vereinfachte Version meines Problems. first ist eigentlich eine ResultSet der SQL-Abfrage, die alle Datensätze auf dem Server sind, second ist eine Liste der lokalen Datensatz (oder in einer anderen lokalen Datenbank verarbeitet), was ich tun möchte, ist alle Datensätze auf dem Server zu löschen (in first), die nicht in der lokalen Datenbank enthalten sind (second), und den fehlenden Datensatz zur entfernten Datenbank hinzufügen. Vielen Dank.


Um

Mein Ziel ist es, schrittweise meine lokale Datenbank zu übertragen (SQLite) auf Remote-Datenbank (MySQL) @Tibrogargan. Die lokalen Datenbanken haben ein Feld namens LocalId (kein Duplikat und nicht der Primärschlüssel) und natürlich andere Inhalte (~ 10 Felder), und abgesehen von den erforderlichen Feldern (~ 5 Feldern) in die entfernte Datenbank habe ich auch ein Feld eingefügt Bestimmen Sie, ob der Datensatz aus der lokalen Datenbank gelöscht wird.

Als weitere Anforderung, ich habe bereits alle lokalen Daten in eine ArrayList, von LocalId auf lokale Datenbank sortiert und haben Zugriff auf alle Datenfern über rs durch LocalId auf Remote-Datenbank sortiert.

Meine frühere Version des Codes war die letzte LocalId in der lokalen Datenbank zu finden, und markieren Sie alle Datensätze auf Remote-Datenbank, deren LocalId ist größer als die maximale LocalId auf der lokalen Datenbank.Es war jedoch korrekt, bis ich feststellte, dass ich die Enddatensätze in der lokalen Datenbank nicht immer lösche. Daher musste ich alle Nachrichten iterieren und die Existenz vergleichen.

Ich weiß nicht, ob es eine "bessere" Lösung gibt, aber scheint, dass, wenn ich alle lokalen Nachrichten auf Remote laden, die Leistung wird schrecklich sein?

Oh, nur zu erwähnen, gibt es nur Dutzende von Nachrichten müssen gelöscht werden und Remote hinzugefügt werden, aus hunderten bis 100 + k Datensätze auf Remote-und lokalen Datensatz vorhanden. Die Logik des Ermittelns, ob ein Datensatz auf Remote als gelöscht gekennzeichnet werden soll, hängt davon ab, ob die entsprechende Nachricht (gleich LocalId) für den lokalen Datensatz vorhanden ist.

+2

Zeigen Sie Ihre aktuelle Implementierung. – dambros

+0

Neben den gewünschten Indizes sind dies nur klassische Mengenoperationen. Siehe hierzu: http://stackoverflow.com/questions/163998/classical-set-operations-for-java-util-collection. (Und Indizes zu erhalten ist trivial) – Tibrogargan

+0

@dambros Dies ist eine vereinfachte Version meiner Implementierung, die aktuelle Implementierung hat eine benutzerdefinierte Klasse und die andere ist SQL ResultSet. Es ist fast unmöglich/unnötig, den gesamten Quellcode einzubinden. –

Antwort

2

Da die Arrays sortiert sind, können Sie einfach beide durchlaufen und dabei nach Duplikaten suchen. Hier ist ein Pseudocode:

//loop over both arrays at once 
int arrayAIndex = 0; 
int arrayBIndex = 0; 
while (arrayAIndex < arrayA.length && arrayBIndex < arrayB.length) { 
    if (arrayA[arrayAIndex] == arrayB[arrayBIndex]) { 
    arrayAIndex++; 
    arrayBIndex++; 
    } else if (arrayA[arrayAIndex] > arrayB[arrayBIndex]) { 
    addToResultB(arrayBIndex); 
    arrayBIndex++; 
    } else if (arrayB[arrayBIndex] > arrayA[arrayAIndex]) { 
    addToResultA(arrayAIndex); 
    arrayAIndex++; 
    } 
} 

//clean up any elements which were not looked at during the above 
while (arrayAIndex < arrayA.length) { 
    addToResultA(arrayAIndex); 
    arrayAIndex++; 
} 
while (arrayBIndex < arrayB.length) { 
    addToResultB(arrayBIndex); 
    arrayBIndex++; 
} 
+0

Gute Antwort. Dies ist die effizienteste Lösung, wenn die Listen groß sind. –

+1

Vorausgesetzt, die Listen sind sortiert :) – Tibrogargan

+0

Das ist ziemlich ähnlich zu meiner bestehenden Implementierung, aber ich hatte Schwierigkeiten bei der "Aufräumen" Bühne. Vielen Dank für deine Tipps! Ich denke mein Problem könnte bald gelöst werden! –

Verwandte Themen