当前位置: 首页 > 面试题库 >

如何在Java 8流上使用foreach循环进行迭代

魏安然
2023-03-14
问题内容

假设我们尝试将可能引发检查异常的lambda应用于Java 8流:

Stream<String> stream = Stream.of("1", "2", "3");
Writer writer = new FileWriter("example.txt");

stream.forEach(s -> writer.append(s)); // Unhandled exception: java.io.IOException

这不会编译

一种解决方法是将检查后的异常嵌套在其中,RuntimeException但是这会使以后的异常处理变得复杂,而且很丑陋:

stream.forEach(s -> {
    try {
        writer.append(s);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
});

另一种解决方法可能是转换限制功能forEach,以普通的旧的foreach


循环是比较友好的检查的异常。

但是幼稚的方法失败了:

for (String s : stream) { // for-each not applicable to expression type 'java.util.stream.Stream<java.lang.String>'
    writer.append(s);
}

for (String s : stream.iterator()) { // foreach not applicable to type 'java.util.Iterator<java.lang.String>'
    writer.append(s);
}

更新资料

为何在Stream <T>不实现Iterable<T>的地方贴了一个回答该问题的技巧。作为副答案本身并不能真正回答该问题。我认为这不足以使这个问题与该问题重复,因为他们问的是不同的事情。


问题答案:

根据定义,foreach循环需要传入一个Iterable。

可以使用匿名类实现:

    for (String s : new Iterable<String>() {
        @Override
        public Iterator<String> iterator() {
            return stream.iterator();
        }
    }) {
        writer.append(s);
    }

使用lambda可以简化此过程,因为它Iterable是一个功能接口:

    for (String s : (Iterable<String>) () -> stream.iterator()) {
        writer.append(s);
    }

可以将其转换为方法参考:

    for (String s : (Iterable<String>) stream::iterator) {
        writer.append(s);
    }

使用中间变量或方法参数可以避免显式强制转换:

    Iterable<String> iterable = stream::iterator;
    for (String s : iterable) {
        writer.append(s);
    }

MavenCentral中还有StreamEx库,它具有开箱即用的可迭代流和其他特权。

以下是一些最流行的问题和方法,它们提供了关于lambda和流中检查异常处理的解决方法:

抛出异常的Java 8Lambda函数?

Java 8:Lambda-Streams,按方法进行过滤(异常)

如何从Java8流中引发CHECKED异常?(不将其包装为未经检查的异常)

jOOλ未选中

科特林 ;)



 类似资料:
  • 替代的解决方法可以是将有限的函数转换为对检查的异常更友好的普通旧foreach循环。 但天真的方法是失败的: 更新 回答这个问题的一个技巧以前在Why does stream not implementing iterable 上发布过?作为旁侧答案并不能真正回答问题本身。我认为这不足以将这个问题定性为那个问题的重复,因为他们问的是不同的问题。

  • 问题内容: 使用以下代码显示我的Twitter个人资料中的朋友列表。我想一次只加载一个特定的数字,例如20,然后在底部为第1-2-3-4-5页的页面提供分页链接(但是,除以限制) **更新**** 这项工作有效,只需要抵消从开始的输出即可。在想什么? 问题答案: 一个非常优雅的解决方案是使用:

  • 本文向大家介绍如何在PowerShell foreach并行循环中使用PSCustomObject?,包括了如何在PowerShell foreach并行循环中使用PSCustomObject?的使用技巧和注意事项,需要的朋友参考一下 要在Foreach并行循环内使用PSCustomObject ,我们首先需要考虑如何在循环内使用变量。 因此,让我们看看是否可以在$out变量中存储或更改值。 示例

  • 如果我试图在java中查找遍历foreach循环的次数,还有比这更好的方法吗? 我知道我可以只使用一个普通的for循环并拥有一个迭代器I,但我只是想知道是否有一种更优雅的方法来使用foreach.tanks in prevair:) 编辑:正如Jon Skeet指出的,上面的代码将新的按钮实例分配给迭代变量。哎呀。基于其他评论,我相信最实用的使用是一个正常循环。这是我要用的版本。谢谢大家的帮助!

  • 我最近开始检查新的Java8特性。 我遇到过这个迭代器-它对集合进行迭代。 比如,我希望它从第2个值开始,然后迭代到第2个最后一个值。或者类似的东西--或者其他元素。 我要怎么做?

  • 我正试图通过Amazon Kinesis(每秒订购10000点)传输大量数据。 为了通过我的碎片最大化每秒的记录,我想在碎片上循环我的请求(我的应用程序逻辑不关心碎片的单个消息会传递到哪里)。 看起来我可以使用我发送到PutRecordsendpoint的列表中的消息的ExplichHashKey参数来执行此操作-但是Amazon留档实际上并没有描述如何使用ExplichHashKey,除了以下的