有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将循环(while和for)转换为流

我已经开始使用Java8,并尝试将代码中的一些循环和旧语法转换为lambdas和streams

例如,我试图将while和for循环转换为stream,但我没有正确地进行转换:

List<String> list = new ArrayList<>();
if (!oldList.isEmpty()) {// old is a List<String>
    Iterator<String> itr = oldList.iterator();
    while (itr.hasNext()) {
        String line = (String) itr.next();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (line.startsWith(entry.getKey())) {
         String newline = line.replace(entry.getKey(),entry.getValue());
                list.add(newline);
            }
        }
    }
}

我想知道是否可以将上面的示例转换为一个流,其中for循环中有一个while循环


共 (4) 个答案

  1. # 1 楼答案

    如上所述,在这里使用流并不能真正增加价值,因为它使代码更难阅读/理解。我知道你更多的是把它当作一种学习练习。也就是说,这样做是一种功能性更强的方法,因为它不会产生从流本身添加到列表中的副作用:

    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());
    
  2. # 2 楼答案

    您可以通过嵌套在从oldList列表创建的流中的流来实现它。嵌套流的作用是使用map中定义的映射器从oldList映射当前值,例如

    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);
    }
    

    以下示例生成如下输出:

    [zcx-qwe, 093]
    

    如果需要,建议的解决方案可以很容易地并行化。功能性方法,无副作用

  3. # 3 楼答案

    为了回答您的问题,这是一个单行:

    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());
    
  4. # 4 楼答案

    我不明白您为什么要在这里使用streams,但这是可能的

    创建一些测试输入:

    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<>();
    

    实际代码:

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

    打印结果:

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

    即:

    xddx
    yddy
    zddz