Java - 根据现有对象列表从流中获取新对象列表

5

我需要使用lambda表达式生成一些新对象的列表。这些新对象继承了现有对象的某些特征。由于没有详细说明可能会很难理解,我将以父母和他们的孩子为例。

我想要根据人员列表生成一个孩子列表(一个人=一个孩子)。孩子只应该继承父母的某些特征(在这种情况下,假设是皮肤颜色)。

由于我有点被迫使用lambda表达式(但也想学习它的工作原理),我尝试了以下解决方案,但无法解决正确映射的问题(我还没有看到过这样的事情,而且我正在进行试错方法)。可能我的构造函数也做得不好。

public class Kid {
    private Colour colour;
    private Person person;

    public Kid(Person person) {
        this.colour = person.getColour();
    }

    public List<Kid> listOfKids() {
        return people.stream()
                     .map(e -> new Kid(e));
    }
}

你必须终止你的语句。添加一个收集器并将结果收集到列表中。 - StaticBeagle
3个回答

4

map之后,你得到的是一个Stream<Kid>,而你需要的是一个List<Kid>,因此你需要通过toList()来收集成一个列表。

return people.stream()
             .map(e -> new Kid(e))
             .collect(Collectors.toList());

如果您需要可变列表,请使用toCollection

return people.stream()
             .map(e -> new Kid(e))
             .collect(Collectors.toCollection(ArrayList::new));

另外,您需要重新考虑设计。
1. 考虑将整个“Person”传递给“Kid”构造函数,改为只传递“Color”(假设它是枚举类型),否则传递表示颜色的“String”。 2. 在“Kid”模型中拥有一个“Person”属性并不是很合理,这就像在说“一个孩子有一个人”...也许您要找的是从“Person”继承的“Kid”,以表明“一个孩子是一个人”。
等等...

3

或者,你可以在map中使用方法引用:

public List<Kid> listOfKids(List<Person> people) {
    return people.stream()
                 .map(Kid::new) // your existing constructor resolves this
                 .collect(Collectors.toList());
}

请注意,虽然构造函数的实现可以编译通过,但如果您想将PersonColour作为Kid类的属性保留,最好使用以下代码:
// assign both attributes of the class within your constructor
public Kid(Person person, Colour colour) {
    this.person = person;
    this.colour = colour;
}

然后更新映射函数如下:

public List<Kid> listOfKids(List<Person> people) {
    return people.stream()
                 .map(p -> new Kid(p, p.getColour())) // map to the updated contructor
                 .collect(Collectors.toList());
}

孩子应该只继承父母的一些特征(例如肤色)。

在这种情况下,您可以通过将您的Kid类从Person类扩展来使用Java中的继承,您所需要的全部内容就是:

public class Kid extends Person {
     public Kid(Colour colour) {
         super(colour);
     }
}

其中,Person类的定义可能如下:

public class Person {
    Colour colour;
    public Person(Colour colour) {
        this.colour = colour;
    }
}

然后,通过这个更改,你的方法会变成这样:
public List<Kid> listOfKids(List<Person> people) {
    return people.stream()
                 .map(p -> new Kid(p.getColour()))
                 .collect(Collectors.toList());
}

0
假设你有一个名为Person的列表,长度为10。由于kib的构造函数调用了person对象的getColour方法,所以你必须检查列表中的person是否为空。
List<Person> people = new ArrayList<>(10);
List<Kid> kids = people.stream()
                       .filter(person -> null!=person)
                       .map(person -> new Kid(person))
                       .collect(Collectors.toList());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接