2017-07-11 3 views
-3

Ich habe ein Problem, bei dem ich glaube, dass ich mehrere Konzepte kombinieren muss, über die ich lese, aber ich kann keinen Weg finden, sie zu kombinieren, die sinnvoll sind oder was am effizientesten wäre. Hier ist meine Situation:Wie durchläuft man eine Liste von Objekten, konvertiert ein Feld, vergleicht es und sortiert nach diesem Feld?

Ich arbeite mit Microservices, weshalb dies so seltsam spezifisch ist. Im Wesentlichen bekomme ich eine Liste von Volume-Objekten von einem anderen Dienst. Ein Volume-Objekt enthält drei Felder, einen String-Typ, ein String-Datum (das tatsächlich die Zeit im Format "HH: mm" darstellt, die Datenmodellierer für die Namenskonventionen verantwortlich machen) und einen int-Abschluss.

Was ich versuche ist, diese Liste von Objekten zu nehmen und nach Datum (Zeit) zu sortieren, dann erstellen Sie eine neue Liste von Objekten, die die gleichen Daten (Zeiten) enthalten, aber unterschiedliche Feldwerte haben Ich mache Berechnungen. Um nach Zeit zu sortieren, glaube ich, dass ich die Zeitfelder in Date-Objekte konvertieren und diese dann vergleichen muss. Ich habe Probleme, die Objekte zu durchlaufen und die konvertierten Felder zu vergleichen. Etwas, das ich fühle, hat mich auf den richtigen Weg gebracht ist dies: How to sort a List<Object> alphabetically using Object name field

Aber ich kann nicht scheinen, dass das funktioniert. Hier ist mein Code:

volumeResources.sort(volumeResources, new Comparator<VolumeResource>(){ 
     @Override 
     public int compare(VolumeResource v1, VolumeResource v2) { 
      SimpleDateFormat format = new SimpleDateFormat("HH:mm"); 
      try { 
       Date d1 = format.parse(v1.getDate()); 
       Date d2 = format.parse(v2.getDate()); 
      } catch (ParseException e) { 
       log.error("Error in parsing string to date. ", e); 
      } 
      return d1.compareTo(d2); 
     } 
    }); 

nun rechts von der Fledermaus, ich weiß, dass dies falsch sein muss, weil ich die VolumeResources v1 und v2 begann zu vergleichen, sondern versucht, die Daten am Ende zu vergleichen. Anstelle der return-Anweisung oben, habe ich versucht, auch die unten, aber ich glaube nicht, dass wird immer funktionieren, weil es nicht wirklich ist das formatierte Objekt zu einem Date-Objekt einstellen:

return format.parse(v1.getDate()).compareTo(format.parse(v2.getDate())); 

Also das ist, wo ich bin verloren. Dies scheint ein ziemlich einfaches Bedürfnis zu sein, wenn es im Pseudocode beschrieben wird, aber ich kann nicht herausfinden, wie es funktional funktioniert. Bonuspunkte, wenn es einen Weg gibt, die anderen Felder zu bevölkern, brauche ich leicht davon. Doppelte Bonuspunkte für die Verwendung von Lambdas oder helfen mir, dies effizient zu machen.

Vielen Dank für alle.

+0

Was _exactly_ ist Ihr Problem? Wie wird Ihr Programm nicht wie erwartet ausgeführt? – Marvin

+0

Kompiliert das überhaupt? – assylias

+0

@Marvin Dieses Hauptproblem versucht herauszufinden, wie eine Liste von Objekten nach der Zeitzeichenfolge sortiert wird. – Crislips

Antwort

1

Wenn Sie Java 8 verwenden und oben die Sortierung nach Zeit (die als String dargestellt wird) kann wie folgt aussehen:

:

volumeResources.sort(new Comparator<VolumeResource>() { 
     @Override 
     public int compare(VolumeResource v1, VolumeResource v2) { 
      return v1.getDate().compareTo(v2.getDate()); 
     } 
    }); 

Prior Java 8 es aussehen sollte

Collections.sort(volumeResources, new Comparator<VolumeResource>() { 
     @Override 
     public int compare(VolumeResource v1, VolumeResource v2) { 
      return v1.getDate().compareTo(v2.getDate()); 
     } 
    }); 

Verwendung Lambda:

volumeResources.sort((v1, v2) -> v1.getDate().compareTo(v2.getDate())); 

Unter der Annahme, dass volumeResources a besiedelte Wandelbare List (nicht null) und alle Einträge Datumsfeld bevölkerte ordnungsgemäß mit einer Wanne ausgebildet Zeit (keine Leerzeichen, Tabulator, oder fehlen führende 0)

Erklärung

nach Ihrer Definition von Datumsfeld ist natürlich als String sortierbar, Sie müssen sie nicht in Java Date Klasse konvertieren.

Ihr Beispiel ein Problem aufgetreten ist durch Java 8 sort Methode in List Schnittstelle in einer Weise definiert verwendet, wie es verwendete, bevor sein Java 8 von Utility-Klasse mit Collections - das ist falsch, brauchen Sie nicht Sammlung als erstes zu liefern Parameter.

+0

Danke für die Hilfe dabei. Ich erwähnte gegenüber Janos, dass ich noch einen Vorbehalt habe, etwas, zu dem ich noch nicht gekommen war, aber ich würde nachsehen, sobald ich das herausgefunden hatte. Nehmen wir an, dass die Zeit "23:30", "24:00", "24:30:", "01:00", "01:30", "02:00" ist. Dies würde bedeuten, dass Mitternacht vorüber ist und danach kommen müsste.Wie kann ich das erklären? – Crislips

+0

@Crislips können Sie ein Beispiel für falsch definierte Zeit mit korrekt definierter Zeit und Ihre Erwartung, wo die Einträge mit der falschen Zeit in der sortierten Liste platziert werden sollten, angeben? –

+0

Wenn ich dich richtig verstehe hier ist was ich meine. Ich muss diese Zeiten in der Reihenfolge des Auftretens sehen, nicht nur nach der Anzahl. Nehmen wir an, ich habe eine @ Vladimir L-Situation, in der die Zeit Mitternacht kreuzt und die Zeiten in der Reihenfolge zunehmen. Ich müsste eine Liste von Objekten haben, die wie folgt sortiert wären: "23:30", "24:00", "24:30:", "01:00", "01:30", "02: 00 ". Aber mit dem aktuellen Code würden sie wie folgt sortiert sein: "01:00", "01:30", "02:00", "23:30", "24:00", "24:30:" – Crislips

1

Ein Datum in Java muss Jahr, Monat, Tag haben. Aber Sie haben solche Werte nicht, Sie haben nur HH:mm (Stunden, Minuten). Verwenden von Daten ist hier nicht geeignet. (Und diese Werte aufrufen "Datum" ist auch seltsam, ich empfehle, umzubenennen.)

Beachten Sie, dass wohlgeformte HH:mm kann alphabetisch sortiert werden, um richtig zu bestellen. Alles, was Sie tun müssen, ist sicherzustellen, dass die Eingabezeiten dem Muster \d\d:\d\d folgen. Wenn Sie zum Beispiel 9:15 erhalten, fügen Sie links ein Padding 0 hinzu. Etwas wie folgt aus:

volumeResources.sort(volumeResources, new Comparator<VolumeResource>() { 
    @Override 
    public int compare(VolumeResource v1, VolumeResource v2) { 
     return sanitized(v1.getDate()).compareTo(sanitized(v2.getDate()); 
    } 
}); 

Die sanitized Methode ist für Sie entsprechend zu implementieren. Wenn die Werte bereits im richtigen Format sind, vom Typ String, dann können Sie diese Anrufe fallen und vereinfachen zu:

 return v1.getDate().compareTo(v2.getDate(); 

Lambda Verwendung:

volumeResources.sort(volumeResources, (v1, v2) -> sanitized(v1.getDate()).compareTo(sanitized(v2.getDate())); 
+0

Danke für den Hinweis. Die Datenkonventionen wurden nicht von mir festgelegt und es lohnt sich nicht, mit den Datenmodellierern zu kämpfen. Ich weiß, dass Datum ein schlecht gewählter Name ist. Ich denke, in dieser Situation hätte ich stattdessen LocalDateTime verwenden können, aber was Sie geschrieben haben, ist definitiv sauberer. Ich habe noch einen Vorbehalt, etwas, zu dem ich noch nicht gekommen war, aber ich würde nachsehen, sobald ich das herausgefunden hatte. Nehmen wir an, dass die Zeit "23:30", "24:00", "24:30:", "01:00", "01:30", "02:00" ist. Dies würde bedeuten, dass Mitternacht vorüber ist und danach kommen müsste. Wie kann ich das erklären? – Crislips

+0

So weit ich weiß, das ist der Umfang der Anforderungen dafür. Ich habe versucht, so knapp wie möglich in meiner ursprünglichen Antwort zu sein, habe aber völlig vergessen, dies zu berücksichtigen. Aber die Zeiten müssen so bleiben, wie sie in der endgültigen Rückkehr sind. – Crislips

+0

@Crislips Alle wichtigen Anforderungen sollten in der Frage angegeben werden. Idealerweise mit Beispieleingaben und erwarteten Ausgaben, insbesondere mit kniffligen Eckenfällen, die Sie bearbeiten müssen. Wenn Sie das vergessen haben, ist es zu spät, um zu ändern, nachdem Sie eine Antwort erhalten haben. Der richtige Weg, um diese Seite in diesem Fall zu benutzen, ist eine neue Frage zu stellen. Und stellen Sie sicher, dass Sie beim nächsten Mal alle wichtigen Details angeben. – janos

Verwandte Themen