【问题标题】:Filter an ArrayList of Objects using Java Streams to return an ArrayList of type String使用 Java 流过滤对象的 ArrayList 以返回 String 类型的 ArrayList
【发布时间】:2021-05-23 19:41:12
【问题描述】:

我在 SO 上找不到确切的解决方案。我有一个Crowd 类,它由一个Crowd 对象组成,它是一个People 类型的数组列表。 People 是一个具有String name, Double bankBalance, Integer numberOfCarsOwned 属性的类。

在我的人群类中,我有以下方法,我试图按以字母 P 开头的名称进行过滤,并返回一个 String 类型的数组列表:

  public ArrayList<String> filterByLetterP(){
       ArrayList<String> filteredNames =  this.crowd.stream()
               .filter(name -> name.getName().contains("P"));
               return filteredNames;
    }

我的错误是: 必填类型ArrayList&lt;String&gt; 提供Stream&lt;People&gt;

注意:我的解决方案必须使用流。如何更正我的解决方案以使其正常工作?

参考信息如下。

People 类定义:

public class People {

    private String name;
    private Double bankBalance;
    private Integer numberOfCarsOwned;

    public People(String name, Double bankBalance, Integer numberOfCarsOwned) {
        this.name = name;
        this.bankBalance = bankBalance;
        this.numberOfCarsOwned = numberOfCarsOwned;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getBankBalance() {
        return bankBalance;
    }

    public void setBankBalance(Double bankBalance) {
        this.bankBalance = bankBalance;
    }

    public Integer getNumberOfCarsOwned() {
        return numberOfCarsOwned;
    }

    public void setNumberOfCarsOwned(Integer numberOfCarsOwned) {
        this.numberOfCarsOwned = numberOfCarsOwned;
    }
}

Crowd类定义:

public class Crowd {

    private ArrayList<People> crowd;

    public Crowd() {
        this.crowd = new ArrayList<>();
    }

    public ArrayList<People> getCrowd() {
        return crowd;
    }

    public void setCrowd(ArrayList<People> crowd) {
        this.crowd = crowd;
    }

    public void addPeopleToCrowd(People people){
        this.crowd.add(people);
    }

    public ArrayList<String> filterByLetterP(){
       ArrayList<String> filteredNames =  this.crowd.stream()
               .filter(name -> name.getName().contains("P"));
               return filteredNames;
    }
}

【问题讨论】:

    标签: java arraylist java-stream


    【解决方案1】:

    有几点需要解决:

    1. 您应该使用String#startsWith 而不是String#contains
    2. 您必须将Stream 映射到People#name
    3. 您错过了收集Stream

    如下图所示:

    public List<String> filterByLetterP() {
        List<String> filteredNames = this.crowd.stream()
                .map(p -> p.getName())
                .filter(s -> s.startsWith("P"))             
                .collect(Collectors.toList());
        return filteredNames;
    }
    

    【讨论】:

    • 这不起作用,因为Collectors.toList() 需要List 类型。我检查过。你能给些建议么?并解释映射的要求?谢谢。
    • @loco - 我已将返回的类型更改为 List&lt;String&gt;。它现在可以工作了。
    • 是的,行得通。谢谢,我会接受你的回答。你还能解释一下 map 在这种情况下的用途吗?如果可能的话,为什么我不能使用 ArrayList?
    • 最好先使用map(),然后检查以P开头的字母:return this.crowd.stream().map(People::getName).filter(name -&gt; name.startsWith("P")).collect(Collectors.toList());
    • Stream#map 是一个中间操作,它通过将给定函数应用于此流的元素来返回一个值。
    【解决方案2】:

    您应该更改过滤器,因为它不会检查以“P”开头的名称:

    public List<String> filterByLetterP(){
        return this.crowd.stream()
                .map(People::getName)
                .filter(name -> name.charAt(0) == 'P')
                .collect(Collectors.toList());
    }
    

    【讨论】:

    • 您的解决方案不允许我使用.charAt 方法 - 可能类型不正确?另外Person 不是一个班级,我的班级是People 所以我相信你可能有错字?谢谢。
    • 你是对的。首先,我应该使用地图,然后过滤名称。它应该是人,而不是人。抱歉打错了!
    猜你喜欢
    • 2017-09-30
    • 2013-07-02
    • 1970-01-01
    • 2016-02-22
    • 2019-07-30
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2016-06-14
    相关资源
    最近更新 更多