Convert an loop (while and for) to stream

前端 未结 4 1530
北海茫月
北海茫月 2021-01-05 00:33

I have started working with Java 8 and trying to convert some loops and old syntax in my code to lambdas and streams.

So for example, I\'m trying to convert this whi

相关标签:
4条回答
  • 2021-01-05 00:37

    As was stated above, using streams here doesn't really add value since it makes the code harder to read/understand. I get that you're doing it more as a learning exercise. That being said, doing something like this is a slightly more functional-style approach as it doesn't have a side effect of adding to the list from within the stream itself:

    list = oldList.stream().flatMap(line->
                map.entrySet().stream()
                        .filter(e->line.startsWith(e.getKey()))
                        .map(filteredEntry->line.replace(filteredEntry.getKey(),filteredEntry.getValue()))
            ).collect(Collectors.toList());
    
    0 讨论(0)
  • 2021-01-05 00:46

    To answer your question, it's a 1-liner:

    List<String> list = oldList.stream()
        .filter(line -> map.keySet().stream().anyMatch(line::startsWith))
        .map(line -> map.entrySet().stream()
            .filter(entry -> line.startsWith(entry.getKey()))
            .map(entry -> line.replace(entry.getKey(), entry.getValue()))
            .findFirst().get())
        .collect(Collectors.toList());
    
    0 讨论(0)
  • 2021-01-05 00:51

    I don't see why you would want to use streams here, but it is possible.

    Create some test input:

    List<String> oldList = Arrays.asList("adda","bddb","cddc");
    Map<String,String> map = new HashMap<>();
    map.put("a", "x");
    map.put("b", "y");
    map.put("c", "z");
    
    List<String> list = new ArrayList<>();
    

    The actual code:

    oldList.stream()
        .forEach(line -> map.entrySet().stream()
                .filter(entry -> line.startsWith(entry.getKey()))
                .forEach(entry -> list.add(line.replace(entry.getKey(),entry.getValue()))));
    

    Print the outcome:

    list.forEach(System.out::println);
    

    Which is:

    xddx
    yddy
    zddz
    
    0 讨论(0)
  • 2021-01-05 00:58

    You can achieve it with a stream nested in a stream created from oldList list. Nested stream plays role of mapping current value from oldList with a mapper defined in map, e.g.

    public static void main(String[] args) {
        final List<String> oldList = Arrays.asList("asd-qwe", "zxc", "123");
        final Map<String, String> map = new HashMap<String, String>() {{
            put("asd", "zcx");
            put("12", "09");
            put("qq", "aa");
        }};
    
        List<String> result = oldList.stream()
                .map(line -> map.entrySet()
                        .stream()
                        .filter(entry -> line.startsWith(entry.getKey()))
                        .map(entry -> line.replace(entry.getKey(), entry.getValue()))
                        .collect(Collectors.toList())
                )
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    
    
        System.out.println(result);
    }
    

    Following example produces output like:

    [zcx-qwe, 093]
    

    Suggested solution can be easily parallelized if needed. Functional approach with no side effects.

    0 讨论(0)
提交回复
热议问题