这在Java流中是可能的吗

这在Java流中是可能的吗,java,foreach,java-stream,Java,Foreach,Java Stream,我只是要求利息。可以通过使用Java的流来制作这样的东西吗?(可能是玩具。stream()…) Set colors=new HashSet(); 玩具。forEach((玩具)->{ if(toy.getType()==Toys.BIKE){ 添加(((Bike)toy.getData()).getFrameColor()); }否则{ 添加(((滑板)toy.getData()).getColor()); } }); 我应该提到,我不可能将颜色存储在超类中。这不是利用继承的正确方法。一个更

我只是要求利息。可以通过使用Java的流来制作这样的东西吗?(可能是玩具。stream()…)

Set colors=new HashSet();
玩具。forEach((玩具)->{
if(toy.getType()==Toys.BIKE){
添加(((Bike)toy.getData()).getFrameColor());
}否则{
添加(((滑板)toy.getData()).getColor());
}
});

我应该提到,我不可能将颜色存储在超类中。

这不是利用继承的正确方法。一个更好的方法是有这样的东西

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());
它利用了多态性,因此您不必在运行时检查实例的类型,这在99%的情况下都是错误的。请注意,您的设计似乎在
玩具
中包含了成分数据

class Toy {
  ToyData data;
}
但是设计没有改变,只需要两次映射,例如
stream().map(Toy::getData).map(ToyData::getActualColor)

根据您的编辑,解决方案必须使用一组接口来标记各种功能,例如:

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());
}
类玩具
{
最终ToyData数据;
公共玩具(ToyData数据){this.data=data;}
public ToyData getData(){return data;}
}
接口ToyData{}
界面颜色
{
Color getColor();
}
类自行车工具ToyData,彩色
{
@重写公共颜色getColor(){return Color.WHITE;}
}
类滑板工具ToyData,彩色
{
@重写公共颜色getColor(){return Color.BLACK;}
}
类Ship实现ToyData{}
公共静态void main(字符串[]args)引发java.lang.Exception
{
列表玩具=新的ArrayList();
玩具。添加(新滑板());
玩具。添加(新自行车());
玩具。添加(新船());
Set=toys.stream()
.map(玩具::getData)
.filter(t->t有色实例)
.map(t->((彩色)t).getColor()
.collect(收集器.toSet());
}

为什么不
toys.map(toy->/*您的代码在这里*/).collect(Collectors.toSet)
?还有,你为什么要玩
自行车
滑板
?请参阅另一章,明确你想要达到的效果。是的。这总是这样。您也可以使用双重分派;但这可能有点过分……我不可能在超类中这样做。我为此做了一个糟糕的示例代码。想想轮子的数量或者类似的东西。没有任何玩具有轮子,因此这种方法不存在。有没有可能在不将所有方法放入超类的情况下使用stream?神秘人:不是没有思考。在这种情况下,一个好的设计是在超类中有一个方法,比如
bool-supportsFeature(Feature-Feature)
,这样您就可以执行
stream().filter(t->t.supportsFeature(Feature.WHEELS)).map(…)
谢谢。你的实际例子给了我一些启发。我正在使用一个界面:)@MysteriousPerson:检查我的编辑,你也可以使用多种界面来获得你想要的东西。唯一的缺点是,你必须使用下行模式,如果在这种情况下是安全的,你也应该避免使用下行模式。
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());
}