Instead of two threads, you can use partitioningBy in Collector
List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine"); Map<Boolean, List<String>> map = strings.stream().collect(Collectors.partitioningBy(s -> s.startsWith("#"))); System.out.println(map);
Output
{false=[this, is, working, fine], true=[
here I used the key as a Boolean , but you can change it to a meaningful string or enumeration
EDIT
If lines can start with some other special characters, you can use groupingBy
List<String> strings = Arrays.asList("#ignored", "this", "is", "#ignored", "working", "fine", "!Someother", "*star"); Function<String, String> classifier = s -> { if (s.matches("^[ !@ #$%^&*]{1}.*")) { return Character.toString(s.charAt(0)); } else { return "others"; } }; Map<String, List<String>> maps = strings.stream().collect(Collectors.groupingBy(classifier)); System.out.println(maps);
Output
{!=[!Someother],
also you can nest groupingBy and partitioningBy
source share