2016-12-02 6 views
2

Nehmen wir an, ich habe eine Schnittstelle namens Importable, die mehrere Implementierungen hat und einer von ihnen ist ImportableImpl.Umwandlung Liste <Staging <Importable>> zu Liste <Staging <ImportableImpl >> mit Java 8 Stream

Ich habe eine Liste einer Klasse Staging, die einen generischen Typ hat: Importable.

Via Java 8 Strom, würde Ich mag die Liste verwandeln:

List<Staging<Importable>> list1 

auf eine Liste:

List<Staging<ImportableImpl>> list2 

Ich bin schon sicher, dass die Liste list1 eine Liste von Staging<ImportableImpl>, so nein ClassCastException kann auftreten. Ich weiß nicht, ob Java diese Art der Transformation mit Generika-Typ autorisiert.

Ich wollte so etwas versuchen:

list1.stream() 
    .map(Staging::getImportable) // retrieve generic type 
    .map(ImportableImpl.class::cast) 
    .collect(Collectors.toList()) 

Aber damit werde ich ein List<ImportableImpl> und keinen List<Staging<ImportableImpl>> bekommen.

+0

Wie erstellen Sie ein "Staging" -Objekt? – BretC

+0

Warum müssen Sie das tun? Vielleicht sollten Sie Ihrer Schnittstelle weitere Methoden hinzufügen. – flakes

Antwort

4

ich wirklich nicht erkennen, was der Zweck Ihrer Versuche, aber Sie sind keine List<Staging<Importable>> ein List<Staging<ImportableImpl>> unabhängig davon drehen erlaubt, was auch immer in der ersten Liste ist. Diese Typen sind nicht konvertierbar.

Die einzige vernünftige Art und Weise zu tun, dass (mit einer Warnung, obwohl) ist:

@SuppressWarnings("unchecked") // if you are sure that all elements are ImportableImpl 
list.stream().map(i -> (Staging<ImportableImpl>) i).collect(Collectors.toList()); 

wo die list eine Art List<Staging<? extends Importable>> hat, keine List<Staging<Importable>>.


Natürlich kann es mit einer Methode Referenz geschrieben werden:

list.stream().map(Staging.class::<ImportableImpl>cast).collect(Collectors.toList()); 
0

Es sieht für mich, dass Sie eine Neuinszenierung Objekt erstellen habe ...

Diese Antwort vorausgesetzt, dass Sie ein Staging Objekt unter Verwendung new Staging<>(thing) erstellen können. Ist das was du brauchst?

list1.stream() 
    .map(s -> new Staging<ImportableImpl>(s.getImportable())) 
    .collect(Collectors.toList()) 
+0

Dies ist die Lösung, die ich gewählt habe, aber ich wollte wissen, ob es eine Möglichkeit gibt, dies zu tun, ohne ein neues Objekt zu erstellen. Alle anderen Bereiche von Staging müssen mit dieser Lösung neu eingestellt werden. –

+0

@louisamoros Wenn Sie sicher sind, dass die Staging-Objekte 'ImportableImpl's enthalten, könnten Sie eine unsichere Umwandlung durchführen, zum Beispiel' .map (s -> (Staging ) ((Staging) s)) ' – BretC

+0

@ louisamoros Ich stimme allerdings mit einigen anderen Kommentaren überein, das ist eine ziemlich unangenehme Sache – BretC

0

Wenn ich dieses Recht haben, als Sie im Grunde wollen nur ausdrücken, dass Ihre list1 tatsächlich bereits eine Liste der Typ ist List<Staging<ImportableImpl>>. So wegwerfen die Abstraktion von Ihrer Schnittstelle zur Verfügung gestellt Importable.

Da zur Laufzeit keiner der generischen Typen existiert, sollten Sie einfach List<Staging<ImportableImpl>> list2 = (List) list1 casten können. Dies ist eine unkontrollierte Besetzung (usung die rohe Form als Zwischenprodukt) und wird einige der Sicherheit, die das Typsystem bietet, entfernen. Es könnte beschädigt werden, wenn jemand ein Objekt vom Typ Staging<AnotherImportableImpl> zu list1 hinzugefügt hat. Die Verwendung von ausgefallenen Konstrukten wie Streams ändert nichts an der Situation. Im Grunde wollen Sie dem Compiler nur sagen, dass Sie sicher sind, dass Sie etwas wissen, das nicht überprüft werden kann.

Verwandte Themen