2017-01-04 4 views
2

Ich muss folgenden Code:Java-Streams: Gruppieren und Sortieren nach einem vorherigen Mapping-Ergebnis?

import java.time.LocalDateTime; 
import java.time.ZoneId; 
import java.time.ZoneOffset; 
import java.time.ZonedDateTime; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Set; 

public class TimeZonesExample 
{ 
    public static void main(String[] args) 
    { 
     Set<String> allZones = ZoneId.getAvailableZoneIds(); 
     LocalDateTime localDateTime = LocalDateTime.now(); 

     List<String> zoneList = new ArrayList<>(allZones); 

     for (String s : zoneList) 
     { 
      ZoneId zoneId = ZoneId.of(s); 
      ZonedDateTime zoneDateTime = localDateTime.atZone(zoneId); 
      ZoneOffset zoneOffset = zoneDateTime.getOffset(); 
      String out = String.format("%35s %10s%n", zoneId, zoneOffset); 

      System.out.printf(out); 
     } 
    } 
} 

Dies erzeugt eine solche Liste:

    Asia/Aden  +03:00 
      America/Cuiaba  -03:00 
        Etc/GMT+9  -09:00 
        Etc/GMT+8  -08:00 
      Africa/Nairobi  +03:00 
      America/Marigot  -04:00 
       Asia/Aqtau  +05:00 
      Pacific/Kwajalein  +12:00 
     America/El_Salvador  -06:00 
      Asia/Pontianak  +07:00 
       Africa/Cairo  +02:00 
      Pacific/Pago_Pago  -11:00 
      Africa/Mbabane  +02:00 
       Asia/Kuching  +08:00 
           .... 

Statt der for-Schleife und vertrauter mit Strom API zu bekommen, habe ich versucht, dies zu einem Strom neu zu schreiben Ergebnis, wobei das Ergebnis nach dem Offset sortiert werden soll. Das Ergebnis sollte wie folgt aussehen:

-09:00 Etc/GMT+9 
-08:00 Etc/GMT+8  
-04:00 America/Marigot  
-03:00 America/Cuiaba 
+03:00 Africa/Nairobi  
+03:00 Asia/Aden 

konnte ich die Offsets (unsortiert) mit dem Ausdruck unten drucken, aber wie sie auf dem zoneIds bewerben? Ich muss mich irgendwie an das vorherige zoneId Mapping-Ergebnis erinnern.

allZones.stream() 
    .map(s -> ZoneId.of(s)) 
    .map(zId -> localDateTime.atZone(zId).getOffset()) 
    .forEach(System.out::println); 
+0

Wenn Sie '.sorted()' direkt vor '.forEach()' einfügen, wird das Programm das tun, was Sie wollen? Ich bin mir nicht sicher, ob ich die Erwartungen hier verstehe. –

+0

@PiotrFindeisen Dies wird in aufsteigender Reihenfolge sortiert, aber dies löst nicht das Problem, wie sie zusammen mit den zoneIds zugeordnet werden. – Bevor

+0

Nur um klar zu sein, du stellst zwei Fragen, richtig? – shmosel

Antwort

3

Sie nicht zurück in den vorherigen Schritt des Stroms erreichen können, das Element vor dem aktuellen Schritt zu erhalten.

Um den Stream zu sortieren, müssen Sie eine Möglichkeit bereitstellen, die Zeichenfolgen mit einem Komparator zu sortieren.

Code Konvertieren in sorted() anwenden, dies erzeugt die Ausgabe, die Sie wollen:

allZones.stream() 
    .sorted(Comparator.<String, ZoneOffset>comparing(s -> localDateTime.atZone(ZoneId.of(s)).getOffset()).reversed()) 
    .map(s -> String.format("%10s %s", localDateTime.atZone(ZoneId.of(s)).getOffset(), ZoneId.of(s))) 
    .forEach(System.out::println); 
+0

Danke, das ist genau das, was ich will. Henriks Lösung ist auch gut, aber Ihre ist ein bisschen besser, weil diese Lösung nur eine Kartenoperation benötigt. – Bevor

1

Wie Piotr sagt, Sie Stream#sorted den Stream sortieren verwenden können.

Ich habe so etwas wie Ihre beabsichtigte Ausgabe von diesem zu tun:

allZones.stream() 
    .map(s -> ZoneId.of(s)) 
    .map(zId -> localDateTime.atZone(zId)) 
    .sorted((o1, o2) -> o1.getOffset().getTotalSeconds() - o2.getOffset().getTotalSeconds()) 
    .forEach(ldt -> System.out.format("%35s %10s%n", ldt.getZone(), ldt.getOffset())); 
+1

Großartig, einfacher als ich dachte. Vielen Dank. – Bevor

5

Sie die ZoneId von ZonedDateTime.getZone() zurück greifen kann. Versuchen Sie folgendes:

ZoneId.getAvailableZoneIds() 
     .stream() 
     .map(ZoneId::of) 
     .map(ZonedDateTime::now) 
     .sorted(Comparator.comparing(ZonedDateTime::getOffset).reversed()) 
     .forEach(zdt -> System.out.println(zdt.getOffset() + "\t" + zdt.getZone())); 
+0

Danke, es ist viel klarer für mich mit Methodenreferenzen. – Bevor

Verwandte Themen