java8 stream 懒加载_JDK8 Stream 从入门到装逼(三)

在lambdas中,可以看到lambda表达式让代码更加简洁、干净、容易理解,并允许不需要创建一个类就可以达到目的。lambdas很好的帮助开发人员更好的表达片段代码的意思,Stream对于集合提供一个抽象计算和Fluent接口更能让程序猿变得爽歪歪。

###1. 构建stream 初始化stream的几个方法

//1. Stream generate 生成无限个无序的stream

Stream stream = Stream.generate(() -> UUID.randomUUID().toString());

// 2. of 构造stream

Stream integerStream = Stream.of(1, 2, 4, 6, 3, 9, 7);

//3.集合构造出stream

Stream> inputStream = Stream.of(

Arrays.asList(1),

Arrays.asList(2, 3),

Arrays.asList(4, 5, 6)

);

###2. 可以怎样用stream

/**

* jdk8 stream 用法

* Created by kaishui on 2016/9/3.

*/

public class JDK_07StreamTest {

static class User {

private String name;

private String password;

public User(String name, String password) {

this.name = name;

this.password = password;

}

//省略getter and setter

}

public static void main(String[] args) {

List userList = new ArrayList();

userList.add(new User("name1", "passowrd1"));

userList.add(new User("name4321", "passowrd4"));

userList.add(new User("name321", "passowrd3"));

userList.add(new User("kaishui", "kaishuiPassword"));

userList.add(new User("name21", "passowrd2"));

//1. 在jdk7之前的代码中,也许我们经常会这样写

List otherUsers = new ArrayList<>();

for (User u : userList) {

//获取含有 "name"的User

if (null != u.getName() && u.getName().indexOf("name") >= 0) {

otherUsers.add(u);

}

}

//按照名字长度排序

Collections.sort(otherUsers, new Comparator() {

@Override

public int compare(User u1, User u2) {

return u1.getName().length() - u2.getName().length();

}

});

//打印

for (User u : otherUsers) {

System.out.println(u.getName());

}

System.out.println("-------我是一条分割线1---------");

System.out.println("-------jdk8 示例---------");

// 2. jdk8 使用stream操作集合

List nameList = userList.stream()

.filter(u -> null != u.getName() && u.getName().indexOf("name") >= 0)//过滤结果

.sorted((u1, u2) -> u1.getName().length() - u2.getName().length())//排序

.map(u -> u.getName())//提取

.collect(Collectors.toList());//把上述步骤后的结果转换成list

//打印

nameList.forEach(System.out::println);

}

}

执行结果:

name1

name21

name321

name4321

-------我是一条分割线1---------

-------jdk8---------

name1

name21

name321

name4321

上面的例子,大概了解stream的用法,下面分点介绍一下: JDK8 collection中已经实现了一个default的stream方法

1. stream() 在集合collection中新建一个stream的管道,有点类似Linux命令中 grep or awk的用法。

2. filter(Predicate) 过滤条件, 看到Predicate应该可以想到就是过滤数据。

3. sorted(Comparator) 根据Comparator排序,英语国家的就是爽,写接口都可以省注释了.

4. map(Function) 提取计算,根据Funtion的作用,我们也知道,输入一个T,返回一个R。

5. collect(Collectors.toList()) 把上述操作stream的结果转为另外一个集合。

如果不了解predicate、function的用法,可以系列篇之函数式接口编程

###3. stream 懒加载

// 1. of 构造 Stream

Stream integerStream = Stream.of(1, 2, 4, 6, 3, 9, 7).map(x -> x / 0);

System.out.println("-------我是一条分割线--------");

执行结果:

-------我是一条分割线--------

上述看到,map(x -> x/0)并没有执行,如果换成下面代码:

// 1. of 构造 Stream

Stream integerStream = Stream.of(1, 2, 4, 6, 3, 9, 7).map(x -> x / 0);

List list = integerStream.collect(Collectors.toList());

System.out.println("-------我是一条分割线--------");

执行结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at com.iu.jdk8.JDK_09StreamLazyLoadTest.lambda$main$0(JDK_09StreamLazyLoadTest.java:19)

at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)

at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)

at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)

at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)

at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)

at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)

at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)

at com.iu.jdk8.JDK_09StreamLazyLoadTest.main(JDK_09StreamLazyLoadTest.java:20)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:497)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

stream只有真正使用到的时候才去真正的执行。

###4. stream 链式编程什么时候才是结束

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

当steam遇上这些方法才算是结束,其他的方法,例如:

map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

还是可以在上一个操作结果上继续操作,例如:根据条件filter -> sort -> map

List userList = new ArrayList();

for (int i = 0; i < 10; i++) {

userList.add(new User("name" + i, "passowrd" + i, i));

}

List nameList = userList.stream()

.filter(u -> null != u.getName() && u.getName().indexOf("name") >= 0)//过滤结果

.sorted((u1, u2) -> u1.getName().length() - u2.getName().length())//排序

.map(u -> u.getName())//提取

.collect(Collectors.toList());//把上述步骤后的结果转换成list

###5. stream api 例子

####5.1 distinct 去重

Stream.of(1, 2, 4, 6, 3, 9, 7, 2, 4, 9, 7).distinct().sorted().forEach(System.out::print);

//执行结果: 1234679

####5.2 skip 跳过条数 limit 限定结果返回几条

Stream.of(1, 2, 4, 6, 3, 9, 7, 2, 4, 9, 7).skip(2).limit(3).forEach(System.out::print);

//执行结果:463

####5.3 fitler 参数为:Predicate 过滤满足条件的结果, Count 统计条数

//获取集合中7的个数

long sum = Stream.of(1, 2, 4, 6, 3, 9, 7, 2, 4, 9, 7).filter(x -> x == 7).count();

System.out.println("sum = " + sum);

//执行结果: sum = 2

####5.4 flatMap 使数据扁平化处理 很多情景,我们都会用到一个类中有List属性,怎样转化成Strean呢,这是flatMap就该出手了

public class JDK_08StreamFlatMapTest {

static class User {

private String name;

private String password;

private int no;

public User(String name, String password, int no) {

this.name = name;

this.password = password;

this.no = no;

}

//省略getter and setter

}

//班级

static class Clazz{

List users;

//省略getter and setter

}

public static void main(String[] args) {

List girlList = new ArrayList();

List boyList = new ArrayList();

for (int i = 0; i < 10; i++) {

girlList.add(new User("girl" + i, "passowrd" + i, i));

boyList.add(new User("boy" + i, "passowrd" + i, i));

}

//班级1

Clazz clazz = new Clazz();

//班级2

Clazz clazz2 = new Clazz();

girlList.addAll(boyList);

clazz.setUsers(girlList);

clazz2.setUsers(girlList);

//clazz stream

Stream clazzSteam = Stream.of(clazz, clazz2);

//clazz stream -> user stream 扁平化

Stream allUserStream = clazzSteam.flatMap(c -> c.getUsers().stream());

System.out.println("两个班级一共多少人:" + allUserStream.count());;

}

}

//执行结果:

两个班级一共多少人:40

####5.5 anyMatch

//是否存在x*x = 81的结果

boolean flag = Stream.of(1, 2, 4, 6, 3, 9, 7, 2, 4, 9, 7).map(x -> x * x).anyMatch(x -> x == 81);

System.out.println(flag);

//执行结果:true

####5.6 reduce Optional reduce(BinaryOperator accumulator) 这个方法的主要作用是把 Stream 元素组合起来,Optional使用方法,请参考网红篇:Java函数式开发——优雅的Optional空指针处理

//clazz stream -> user stream

Stream allUserStream = clazzSteam.flatMap(c -> c.getUsers().stream());

//串起所有名字 想了解optional用法可以参考:http://my.oschina.net/chkui/blog/739034

Optional names = allUserStream.

map(User::getName).sorted((first, second) -> first.compareTo(second))

.reduce((first, second) -> first + " *** " + second);

System.out.println(names.get());

执行结果:

boy0 *** boy0 *** boy1 *** boy1 *** boy2 *** boy2 *** boy3 *** boy3 *** boy4 *** boy4 *** boy5 *** boy5 *** boy6 *** boy6 *** boy7 *** boy7 *** boy8 *** boy8 *** boy9 *** boy9 *** girl0 *** girl0 *** girl1 *** girl1 *** girl2 *** girl2 *** girl3 *** girl3 *** girl4 *** girl4 *** girl5 *** girl5 *** girl6 *** girl6 *** girl7 *** girl7 *** girl8 *** girl8 *** girl9 *** girl9

####5.7 Parallel 并行运行 vs 普通stream操作

long startTime = System.nanoTime();

Map> numbersPerThread = IntStream.rangeClosed(1, 100000)

.parallel()

.boxed()

.collect(Collectors.groupingBy(i -> Thread.currentThread().getName()));

long runTime = System.nanoTime() - startTime;

System.out.println("运行时间:" + String.valueOf(runTime));

//运行时间:159695489

long startTime = System.nanoTime();

Map> numbersPerThread = IntStream.rangeClosed(1, 100000)

.boxed()

.collect(Collectors.groupingBy(i -> Thread.currentThread().getName()));

long runTime = System.nanoTime() - startTime;

System.out.println("运行时间:" + String.valueOf(runTime));

//运行时间:94576511

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值