Java8集合遍历方式与Stream流
小tips:本文不会介绍所有遍历的方式,如果你并不明白什么是集合,那么推荐你去看我的入门文章:集合框架
Java8集合遍历方式与Stream流
Java8集合遍历方式
使用Iterator 接口操作集合
Iterator 接口是 Java 集合框架的成员,这个接口主要用于遍历Collection集合中的元素,所以也被称为迭代器。Iterator 必须依附于Collection对象,有一个Iterator 对象,必然就有一个Collection对象。
1 |
|
当使用迭代器访问元素时,Collection集合里面地元素是不能通过remove来删除的,只能通过Iterator的remove才能删除,实际上当使用foreach来循环的时候也是同样的。而且在使用这两种循环的时候,你是不能在循环体内修改他的值。如果运行上面的代码会报
1 |
|
Iterator迭代器采用得是快速失败机制,一旦在迭代过程中检测到该集合已被修改(可能被程序中其他线程修改),程序立即引发 ConcurrentModificationException (也类似于上图的错误)
使用foreach循环遍历集合
1 |
|
此段代码也会触发ConcurrentModificationException异常,foreach 循环中的迭代变量也不是集合元素本身, 系统只是依次把集合元素的值赋给迭代 变量, 因此在 foreach 循环中修改迭代变量的值也没有任何 实际意义。
上述两种方式也不总是会异常,当book.equals("Java")
换成book.equals("疯狂")
就不会引起错误,可能是因为需要判断的对象在遍历的末尾,当然这只是某种特殊情况,仍然不建议在使用这两种方式时修改集合
使用Predicate操作集合
Java8新增了一个removeIf( Predicate filter)
方法,该方法可以批量删除符合filter条件的所有元素。Predicate也是函数式接口,因此可使用Lambda表达式作为参数。不过重点不在于删除,而是我们可以通过这个类来编写属于自己的统计方式。
1 |
|
使用Stream操作集合
Java8新增了Stream、IntStream、LongStream、DoubleStream等流式API。什么是Stream流呢?你假象一下,早上起床,是不是要先掀开被子-穿拖鞋-刷牙洗脸-开门去上班。这是一套早上起床流程,Stream流正是这样,你创建一个流,在每个节点都可以筛选或者改变一些东西,然后在最后结束这个流。
1 |
|
Stream流中有两种方法:
中间方法:中间操作允许流保持打开状态,并允许调用流的后续方法,上述中map就是中间方法。更多详情方法请查询API文档。
方法名 描述 filter(Predicate predicate) 过滤Stream中所有不符合predicate的元素 mapToXxx(ToXxxFunction mapper) Xxx是包装类,该方法返回的流中包含了ToXxxFunction转换生成的所有元素 peek(Consumer action) 依次对每个元素执行一些操作,返回的流与原有的流包含相同的元素。该方法主要用于调试 distinct() 用于排序流中所有重复元素。这是一个有状态的方法,比较是否相同是根据该元素的equals返回true sorted() 保证流中的元素在后续的访问中处于有序状态。这是一个有状态的方法。 limit(long maxSize) 保证对该流的后续访问中最大允许方法的元素个数。这是一个有状态的、短路方法。 末端方法:末端方法是对流的最终操作。当某个流执行末端方法后,这个流就会被消耗结束,不能继续执行后续方法。更多详情方法请查询API文档。
方法名 描述 forEach(Consumer action) 遍历流中所有元素,对每个元素执行action toArray() 将流中所有元素转换为一个数组 reduce() 该方法有三个重载的版本,都用于通过某种操作来合并流中的元素 min() 返回流中最小值 max() 返回流中最大值 count() 返回流中所有元素的数量 anyMatch(Predicate predicate) 判断流中是否至少包含一个元素符合 allMatch(Predicate predicate) 判断流中每个元素是否都符合Predicate noneMatch(Predicate predicate) 判断流中是否所有元素都不符合Predicate条件 findFirst() 返回流中第一个元素 findAny() 返回流中任意一个元素 collect() 对流的元素执行可变的约简操作,把流输出为其他类型。一般用Collectors.toList()来返回集合,具体其他方法还挺复杂的。
流的方法还有如下两个特征
有状态的方法:这种方法会给流增加一些新的状态,比如元素唯一,元素最大数量,元素排序
短路方法:尽早结束对流的操作,不必检查所有的元素
使用流来改进之前我们自定义的方法
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!