6

I have 2 Lists, the one contains a list of numbers and the other a list of names. I have prefixed the names with a number from the first list, followed by an underscore. I want to filter the second list based on all the numbers found in the first list.

What I have tried.

List<String> numberList = new ArrayList<>(); numberList.add("1_"); numberList.add("9_"); List<String> nameList = new ArrayList<>(); nameList.add("1_John"); nameList.add("2_Peter"); nameList.add("9_Susan"); List<String> filteredList = Stream.of(numberList.toArray(new String[0])) .filter(str -> nameList.stream().anyMatch(str::startsWith)) .collect(Collectors.toList()); 

The code above runs with no error, but the filteredList is empty. Clearly I am doing something wrong.

The filteredList should contain only:

1_John

9_Susan

1
  • To create a stream from a Collection just use the existing API as Stream.of(numberList.toArray(new String[0])) => numberList.stream(). While you're actually iterating on the incorrect list using the streams. It should be the second list to iterate on and first used to filter in. Commented May 28, 2019 at 6:36

4 Answers 4

5

You call startsWith on the wrong Strings (for example, you test if "1_".startsWith("1_John") instead of "1_John".startsWith("1_")).

You should stream over nameList and use numberList for the filtering:

List<String> filteredList = nameList.stream() .filter(str -> numberList.stream().anyMatch(str::startsWith)) .collect(Collectors.toList()); 

P.S. Stream.of(numberList.toArray(new String[0])) is redundant. Use numberList.stream() instead.

Sign up to request clarification or add additional context in comments.

Comments

4

As an alternate to Eran's solution, you can also use a combination of removeIf and noneMatch as follows:

List<String> filteredList = new ArrayList<>(nameList); filteredList.removeIf(str -> numberList.stream().noneMatch(str::startsWith)); 

1 Comment

Thanks, I will also give this a try to see it in action.
0

Another attempt to give a solution could be to use contains , though the actual implementation of startsWith and contains are different but in OP case both will fetch the same result.

List<String> strList = nameList.stream().filter(s->numberList.stream().anyMatch(s::contains)).collect(Collectors.toList()); 

Output:

[1_John, 9_Susan]

Comments

0
List<String> numberList = new ArrayList<>(); numberList.add("1_"); numberList.add("9_"); List<String> nameList = new ArrayList<>(); nameList.add("1_John"); nameList.add("2_Peter"); nameList.add("9_Susan"); 

Following is the correct code:

enter image description here

Your code uses the following:

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.