2016-06-04 7 views
-1

Ich bin nur um Interesse bitten. Ist es möglich, so etwas mithilfe von Java Stream zu machen? (Wäre toys.stream() ...)Ist dies mit Java Stream möglich

Set<String> colors = new HashSet<>(); 

toys.forEach((toy) -> { 
    if (toy.getType() == Toys.BIKE) { 
     colors.add(((Bike) toy.getData()).getFrameColor()); 
    } else { 
     colors.add(((Skateboard) toy.getData()).getColor()); 
    } 
}); 

soll ich erwähnen, dass es nicht möglich ist für mich die Farbe in einer übergeordneten Klasse zu speichern.

+1

Warum nicht 'toys.map (Spielzeug ->/* Code hier * /) .collect (Collectors.toSet) '? P.S. Warum spielst du auf 'Bike' und' SkateBoard'? –

+0

Siehe http://stackoverflow.com/questions/122105/what-is-the-best-way-to-filter-a-java-collection auch – Tunaki

+0

Klären Sie, was Sie Wirkung versuchen zu erreichen. – Kamran

Antwort

4

Das ist keine geeignete Methode zur Vererbung. Eine bessere Möglichkeit wäre, etwas zu haben, wie

abstract class Toy { 
    abstract Color getActualColor(); 
} 

class Bike { 
    @Override Color getActualColor() { return getFrameColor(); } 
} 

class Skateboard { 
    @Override Color getActualColor() { return getColor(); } 
} 

... 
toys.stream().map(Toy::getActualColor).collect(Collectors.toSet()); 

Welche Verwendung von Polymorphismus macht, so dass Sie nicht über den Typ einer Instanz zur Laufzeit haben zu prüfen, die 99% der Zeit schlecht ist. Beachten Sie, dass Ihr Design scheint die Daten durch die Zusammensetzung innerhalb Toy zu haben, eine Art

class Toy { 
    ToyData data; 
} 

aber das Design ändert sich nicht, Sie haben nur zweimal abbildet, zB stream().map(Toy::getData).map(ToyData::getActualColor).

Nach Ihren Änderungen eine Lösung würde eine Reihe von Schnittstellen zu verwenden, hat die verschiedenen Funktionen zu markieren, so etwas wie:

class Toy 
{ 
    final ToyData data; 

    public Toy(ToyData data) { this.data = data; } 

    public ToyData getData() { return data; } 
} 

interface ToyData { } 

interface Colored 
{ 
    Color getColor(); 
} 

class Bike implements ToyData, Colored 
{ 
    @Override public Color getColor() { return Color.WHITE; } 
} 

class Skateboard implements ToyData, Colored 
{ 
    @Override public Color getColor() { return Color.BLACK; } 
} 

class Ship implements ToyData { } 


public static void main (String[] args) throws java.lang.Exception 
{ 
    List<Toy> toys = new ArrayList<>(); 

    toys.add(new Skateboard()); 
    toys.add(new Bike()); 
    toys.add(new Ship()); 

    Set<Color> = toys.stream() 
        .map(Toy::getData) 
        .filter(t -> t instanceof Colored) 
        .map(t -> ((Colored)t).getColor()) 
        .collect(Collectors.toSet()); 
} 
+0

Yup. Dies. Immer das. Sie könnten auch Doppelversand verwenden; aber das könnte übertrieben sein ... –

+0

Es ist mir nicht möglich, dies in einer Superklasse zu tun. Ich habe dafür einen schlechten Beispielcode erstellt. Denken Sie an die Anzahl der Räder oder so ähnlich. Kein Spielzeug hat Räder, daher gibt es diese Methode nicht. Ist es möglich, Stream zu verwenden, ohne alle Methoods in die Superklasse zu setzen? – MysteriousPerson

+0

@MysteriousPerson: nicht ohne Reflexion. Ein guter Entwurf in dieser Situation wäre, eine Methode in der Oberklasse zu haben, wie 'bool supportsFeature (Feature feature)', so dass du 'stream() filter (t -> t.supportsFeature (Feature.WHEELS)). Map (...) ' – Jack