我只想要感兴趣。是否有可能通过使用Java的Stream来制作这样的东西? (将是toys.stream()...)
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());
}
});
我应该提一下,我不可能将颜色存储在超类中。
答案 0 :(得分:4)
这不是利用继承的正确方法。更好的方法是拥有像
这样的东西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%的时间都是不好的。请注意,您的设计似乎是Toy
内的组合数据,而不是
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());
}