Accumulate a Java Stream and only then process it

前端 未结 1 1403
失恋的感觉
失恋的感觉 2020-12-21 21:08

I had a document that looked like the following:

data.txt

100, \"some text\"
101, \"more text\"
102, \"even more text\"

I processed

相关标签:
1条回答
  • 2020-12-21 21:26

    This is a job for java.util.Scanner. With the upcoming Java 9, you would write:

    List<MyClass> result;
    try(Scanner s=new Scanner(Paths.get("data.txt"))) {
        result = s.findAll("(\\d{1,3}),\\s*\"([^\"]*)\"")
                    //MyClass(int id, String text)
        .map(m -> new MyClass(Integer.parseInt(m.group(1)), m.group(2))) 
        .collect(Collectors.toList());
    }
    result.forEach(System.out::println);
    

    but since the Stream producing findAll does not exist under Java 8, we’ll need a helper method:

    private static Stream<MatchResult> matches(Scanner s, String pattern) {
        Pattern compiled=Pattern.compile(pattern);
        return StreamSupport.stream(
            new Spliterators.AbstractSpliterator<MatchResult>(1000,
                             Spliterator.ORDERED|Spliterator.NONNULL) {
            @Override
            public boolean tryAdvance(Consumer<? super MatchResult> action) {
                if(s.findWithinHorizon(compiled, 0)==null) return false;
                action.accept(s.match());
                return true;
            }
        }, false);
    }
    

    Replacing findAll with this helper method, we get

    List<MyClass> result;
    try(Scanner s=new Scanner(Paths.get("data.txt"))) {
    
        result = matches(s, "(\\d{1,3}),\\s*\"([^\"]*)\"")
                   // MyClass(int id, String text)
        .map(m -> new MyClass(Integer.parseInt(m.group(1)), m.group(2)))
        .collect(Collectors.toList());
    }
    
    0 讨论(0)
提交回复
热议问题