java 中Stream不可不知的几个问题

目录

一大堆初始化函数。

Stream中间操作为懒调用

Java9提供了新的函数takeWhile


 Java8 中的的stream非常好用,大部分的集合操作都可以实现。关于Stream的文章很多。这里只简单介绍一点调用问题。以便更好的理解Stream

一大堆初始化函数

基本上任意类型的数据,均可找到相应的方法转到Steam

Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();
Stream<String> streamOfArray = Stream.of("a", "b", "c");
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);

Stream<String> streamBuilder = Stream.<String> builder().add("a").add("b").add("c").build();

Stream<String> streamGenerated = Stream.generate(() -> "element").limit(10);
Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);
IntStream intStream = IntStream.range(1, 3);
LongStream longStream = LongStream.rangeClosed(1, 3);

Random random = new Random();
DoubleStream doubleStream = random.doubles(3);

IntStream streamOfChars = "abc".chars();
Stream<String> streamOfString = Pattern.compile(", ").splitAsStream("a, b, c");

Path path = Paths.get("C:\\file.txt");
Stream<String> streamOfStrings = Files.lines(path);
Stream<String> streamWithCharset = Files.lines(path, Charset.forName("UTF-8"));

我们实例化一个Stream,中间操作可以一直进行,直到遇到终止函数。而且每个Stream只能有一个终止操作,中间操作可以有若干个。终止函数将返回一个已经被修改的Stream。

List<String> list = 
        Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck")
.filter(v->v.length() == 3)
.sorted()
.collect(Collectors.toList());

filter和sorted都是中间操作。而collect就是终止操作。此段代码会返回名称长度为3,并且会对这个数据进行排序后输出转换为List操作。

如果还有其他的中间操作。比如根据条件再次过滤。比如将每个字符串加上一个特殊字符等中间操作,都可以加在终止函数之前。

其他有关Stream的操作文档请自行搜索学习。

Stream中间操作为懒调用

所有的Stream中间操作,都是懒调用。意思是终止函数之前的函数,会根据最后的终止函数而决定是否被调用。

例如下代码:我们增加一个计数器counter

List<String> list = Arrays.asList("abc1", "abc2", "abc3");
AtomicInteger counter = new AtomicInteger(0);
Stream<String> stream = list.stream().filter(element -> {
            counter.addAndGet(1);
            return element.contains("2");
});
System.out.println(counter.get());

好像这个counter最终结果应该是3,实际结果:由于没有终止操作函数。这个计数器最后输出为0

意思是,根本filer这个函数就没有运行。但是我们加上一个终止函数,比如findFirst()

List<String> list = Arrays.asList("abc1", "abc2", "abc3");
AtomicInteger counter = new AtomicInteger(0);
Optional<String> v = list.stream().filter(element -> {
            counter.addAndGet(1);
            return element.contains("2");
}).findFirst();
System.out.println(counter.get());

此时counter的最终输出结果是 2,为什么?继续往下看

再来看下面的例子:

List<String> list = Arrays.asList("abc1", "abc2", "abc3");
Optional<String> stream = list.stream().filter(element -> {
            System.out.println("filter() was called");
            return element.contains("2");
}).map(element -> {
            System.out.println("map() was called");
            return element.toUpperCase();
}).findFirst();

输出结果是:

filter() was called
filter() was called
map() was called

filter被调用了2次,map被调用了一次。是因为findFirst终止操作只需要一个结果。而filter的第一个不满足条件,就继续判断第二个数据。发现符合filter条件。就不再判断后边的数据。而由于结果findFirst只需要一个结果。所以map操作只运行一次就不再继续。

如果有兴趣,请实验以下代码结果,并验证是否和自己想想的结果一样?

List<String> list = Arrays.asList("abc1", "abc2", "abc3");
AtomicInteger counter = new AtomicInteger(0);
long size = list.stream().map(element -> {
            counter.addAndGet(1);
            return element.substring(0, 3);
}).skip(2).count();
System.out.println(size);
System.out.println(counter.get());

Java9提供了新的函数takeWhile

类似于for循环的break及时终止Stream

Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck")
  .takeWhile(n -> n.length() % 2 != 0)
  .forEach(System.out::println);

如果我们运行以上代码,得到的结果是:

cat
dog

相比较下,使用for循环的代码,应该是:

//java9 中才有List.of
List<String> list = List.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
for (String item : list)
{
    if (item.length() % 2 == 0)
    {
        break;
    }
    System.out.println(item);
}

本程序所有源码见:java stream 初始化及懒调用源代码https://download.csdn.net/download/2301_77345366/87666186

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值