'Adding objects to two lists from a stream
how can I add objects in two different lists from a stream in another way?
here's an example
ArrayList<String> someList = new ArrayList();
someList.add("123QWE");
someList.add("QWE123");
//...
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
someList.stream().forEach(string -> {
if (Character.isDigit(string.charAt(0))
{
list1.add(string);
}
else
{
list2.add(string);
}
}
Solution 1:[1]
Based on your updated question I would still go with a simple loop. Streams are great for some operations but their internals are quite complex. You can always call Collections.sort() on each list once the modifications to each list are complete.
This is not to say it can't be done with streams. But imho, there is nothing gained by doing so.
ArrayList<Object> list1 = new ArrayList<>();
ArrayList<Object> list2 = new ArrayList<>();
for (String str : someList) {
if (Character.isDigit(str.charAt(0)) {
list1.add(str);
} else {
list2.add(str);
}
}
Collections.sort(list1);
Collections.sort(list2);
But if you really want to use streams then here is one way. It includes sorting (which you said you wanted in a comment) after you get done segregating the original list.
- define a
sortedListcollector to share for both streams. Not necessary but reduces code. - the collector first collects them into a list.
- then sorts them.
Collector<String,?,List<String>> sortedList = Collectors.collectingAndThen(
Collectors.toList(),
lst->{Collections.sort(lst); return lst;});
List<String> someList = List.of("B","3C","4E","A", "2B","C", "E", "1A");
List<String> list1 = someList.stream()
.filter(str -> !Character.isDigit(str.charAt(0)))
.collect(sortedList);
List<String> list2 = someList.stream()
.filter(str -> Character.isDigit(str.charAt(0)))
.collect(sortedList);
System.out.println(list1);
System.out.println(list2);
prints
[A, B, C, E]
[1A, 2B, 3C, 4E]
Solution 2:[2]
Well, using Streams, you could also achieve this with a single stream:
Map<Boolean, List<String>> partition = someList.stream()
.collect(Collectors.partitioningBy(str -> Character.isDigit(str.charAt(0))));
Now
partition.get(true)returns the list with string starting with digits;partition.get(false)returns the others.
Solution 3:[3]
Use stream.filter() and collect() like this:
list1 = someList.stream().filter(str -> Character.isDigit(str.charAt(0))).collect(Collectors.toList());
list2 = someList.stream().filter(str -> !Character.isDigit(str.charAt(0))).collect(Collectors.toList());
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | MC Emperor |
| Solution 3 |
