如何将返回整数的函数传入Java 8 Stream API的limit方法
问题描述
现有列表:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
使用Java 8 Stream调用skip(1)跳过第一个元素后,希望将流限制到元素8(对应原列表索引7),但不想硬编码limit(7),而是通过判断元素等于8来获取其索引,再传入limit。目前已经实现了自定义getInd方法,想知道能不能用Lambda表达式实现这个需求,当前尝试的代码如下:
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); l.stream() .skip(1) .limit() .forEach(n->System.out.println(n));
已实现的自定义方法代码:
package classes; import java.util.*; public class Test { public static void main(String[] args) { List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int n = getInd(8, l); l.stream() .skip(1) .limit(n) .forEach(System.out::println); } static int getInd(int n, List<Integer> list) { for (int i = 0; i < list.size(); i++) { if (list.get(i) == n) {return i;} } return -1; } }
解决方案
最简单的方式:直接用List自带的indexOf
压根不用写自定义方法,List本身就提供了indexOf方法,能直接返回元素在列表里的索引,替换掉你写的getInd就行:
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 直接拿元素8的原索引 int targetIndex = l.indexOf(8); l.stream() .skip(1) .limit(targetIndex) .forEach(System.out::println);
运行之后会输出2、3、4、5、6、7、8,完全符合你要的效果。
用Lambda/Stream实现索引查找
如果非要用Lambda风格的写法来找索引,可以用IntStream遍历列表的索引,筛选出匹配元素的位置:
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 用IntStream生成索引流,找到第一个等于8的元素的索引 int targetIndex = IntStream.range(0, l.size()) .filter(i -> l.get(i) == 8) .findFirst() .orElse(-1); // 找不到元素时返回-1,防止空指针 l.stream() .skip(1) .limit(targetIndex) .forEach(System.out::println);
这里IntStream.range会生成从0到列表长度-1的索引,filter挑出对应元素是8的索引,findFirst取第一个匹配的结果(毕竟你的列表里元素不重复),orElse处理找不到目标元素的情况。
补充说明
- 原列表调用
skip(1)后,流从原索引1的元素开始,而limit(targetIndex)里的targetIndex是原列表的索引7,所以流会包含原索引1到7的元素,刚好到8为止,完全符合需求。 - 如果列表里有重复元素,不管是
indexOf还是上面的Stream写法,都会返回第一个匹配元素的索引,和你自定义的getInd逻辑完全一致。
内容的提问来源于stack exchange,提问作者Debendra Nath Mukherjee
相关产品推荐
相关产品推荐

