Skip to content

Filter an ArrayList of Objects using Java Streams to return an ArrayList of type String

I can’t find an exact solution for this on SO. I have a Crowd class which consists of a Crowd object which is an arraylist of type People. People is a class with properties String name, Double bankBalance, Integer numberOfCarsOwned.

In my crowd class I have the following method whereby I seek to filter by names beginning with the letter P and return these an arraylist of type String:

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

My error is: required type ArrayList<String> provided Stream<People>

Note: My solution must make use of streams. How can I correct my solution to get it to work?

Reference info below.

People class definition:

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;
    }
}

Crowdclass definition:

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;
    }
}

Answer

A couple of things needs to be addressed:

  1. You should use String#startsWith instead of String#contains.
  2. You have to map the Stream to People#name.
  3. You have missed collecting the Stream.

Do it as shown below:

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