Java8 Stream流遍历 如何使用索引

1. 问题来源

Java8Stream流为我们的遍历集合带来了方便,基本可以取代for循环了。但是有一些情况需要知道当前遍历的索引,使用for循环当然可以轻易获得,但使用stream就很难了。
比如下面这个情况:
有一个集合list,里面存储的是引用类型。
使用for循环可以轻易的操作索引i

for (int i = 0; i < list.size(); i++){
	System.out.println(list.get(i));
	System.out.println(i);
}

使用Stream流遍历list如下,其中handle是一个方法,想在handle方法里面拿到当前索引是很困难的。

list.stream().map(t -> handle(t)).collect(Collectors.toList());
2. 解决办法

使用IntStream流来构造一个Int类型的流出来,然后遍历这个Int的流,list中的对象可以通过get方法来取。具体解决代码如下:

IntStream.range(0, lists.size())
         .mapToObj(i -> handle(lists.get(i), i))
         .collect(Collectors.toList());

可以看到代码里的这一句:handle(lists.get(i), i),这样就成功的把索引带入到了handle方法中。

需要注意的是:在流中必须使用mapToObj,而不能使用map映射

3. map映射和mapToObj的区别

首先Stream流下面的类包含了IntStream, LongStream, DoubleStream

  1. 那么究竟下面两者有什么区别呢?
Stream<Integer> // 包装类型
IntStream	//基本类型

所以对于mapToObjmapToInt也是同样的
mapToObj 方法主要是将Stream中的元素进行装箱操作, 转换成一个引用类型的值。
mapToInt 方法是将Stream中的 元素转换成基本类型int
比如下面的例子

Stream s = IntStream.of(4, 5, 6).mapToObj(e -> e); //mapToObj method is needed
IntStream is = Stream.of(4, 5, 6).mapToInt(e -> e); //mapToInt method is needed

可以看到Stream是包装类型,所以想要把IntStream基本类型流转化成包装类型,就需要使用mapToObj

  1. 上面两个mapToObj和mapToInt是进行类型的转化,那么map的作用呢?
    map不进行类型转化,如果原来流中是基本类型,map映射完应当还是基本类型,如果原来是包装类型,映射完应当还是包装类型
    比如下面这个例子:
IntStream.of(1, 2, 3, 4, 5, 6, 7).map(elem -> elem * 10).forEach(System.out::println);

这也就解释了,为什么上面的第二节解决办法里面,用map不行,而需要mapToObj,因为那里做了一个基本类型到包装类型的转化

3. 总结
  1. 使用IntStream可以灵活的操作对象和获取索引。
  2. map不进行包装和基本类型的转化,mapToObj是基本转为包装,mapToInt是包装转为基本。
END
参考

Java 8之基本类型优化
Java Stream difference between map and mapToObj
How to get element index when using a stream to traverse a list?

Java集合可以使用Java 8引入的Stream的方式。Stream提供了一种对集合进行操作的高阶抽象。通过使用Stream,可以使用类似于SQL语句的方式对集合进行查询和操作。下面是一个使用Stream流遍集合的示例代码: ```java import java.util.ArrayList; import java.util.stream.Stream; public class StreamDemo { public static void main(String[] args) { ArrayList<String> webSites = new ArrayList<>(); webSites.add("baidu"); webSites.add("google"); webSites.add("weibo"); // 使用Stream流遍集合 webSites.stream().forEach(e -> { System.out.println(e); }); } } ``` 在这个示例中,我们创建了一个ArrayList集合`webSites`,并向其中添加了三个元素。然后,我们使用`stream()`方法将集合转换为,之后使用`forEach()`方法对中的每个元素进行遍,并将元素打印出来。这样就可以使用Stream对集合进行遍了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Stream流遍集合,对集合中数据进行过滤](https://blog.youkuaiyun.com/qq_40649503/article/details/108762599)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Java8Stream代替传统的集合遍](https://blog.youkuaiyun.com/joshua317/article/details/128244212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值