1 2 3 4 5 6
| 作者: 夜泊1990 企鹅: 1611756908 鹅群: 948233848 邮箱: hd1611756908@163.com 博客: https://hd1611756908.github.io/ B 站: https://space.bilibili.com/514155929/
|
JDK发布时间
JDK8新特性
1 2 3 4 5 6
| 1. 日期时间API 2. Lambda表达式 3. 默认方法 4. 函数式接口 5. 方法引用 6. Stream API
|
第一章 日期和时间
第1节 传统的日期时间的缺陷
1 2 3 4
| 1. 传统的时间处理API设计很差,Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类 2. 用于格式化和解析的类却在java.text包中定义 3. java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,这两个类还设计成相同的名字 5. 时区处理麻烦,传统的日期/时间API没有时区支持,所以又引入了java.util.Calendar和java.util.TimeZone类
|
第2节 新的日期时间API的优点
1
| JDK8的java.time包下涵盖了所有处理日期、时间、日期/时间、时区等的操作
|
2.1 时间的创建
2.1.1 使用now函数
1 2 3 4 5 6 7 8 9 10 11 12
|
LocalDateTime localDateTime = LocalDateTime.now(); LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now();
|
2.2.2 使用of函数
1 2 3 4 5 6 7 8 9 10 11
|
LocalDateTime localDateTime1 = LocalDateTime.of(2018, 12, 12, 12, 12, 12);
LocalDate localDate1 = LocalDate.of(2020, 1, 1);
LocalTime localTime1 = LocalTime.of(22, 22, 22);
|
2.2.3 字符串创建
1 2 3 4 5 6 7 8 9 10 11 12
|
LocalDateTime localDateTime2 = LocalDateTime.parse("2018-12-30T12:10:59");
LocalDateTime localDateTime3 = LocalDateTime.parse("2018-12-30T12:10:59.120");
LocalDateTime localDateTime4 = LocalDateTime.parse("2018-12-30 12:10:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime localDateTime5 = LocalDateTime.parse("2019年12月30日 12时10分59秒",DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒"));
|
2.2.4 带时区创建
1 2 3 4 5 6 7 8 9 10 11 12
|
LocalDateTime localDateTime6 = LocalDateTime.now(ZoneId.of("UTC"));
System.out.println("utc: "+localDateTime6);
LocalDateTime localDateTime7 = LocalDateTime.now(ZoneId.of("+8")); System.out.println("GMT8: "+localDateTime7);
|
2.2 时间的获取
获取年月日
1 2 3 4 5 6 7 8
| int year = currentDateTime.getYear();
Month month = currentDateTime.getMonth();
int monthValue = currentDateTime.getMonthValue();
int dayOfMonth = currentDateTime.getDayOfMonth();
|
获取时分秒
1 2 3 4 5 6
| int hour = currentDateTime.getHour();
int minute = currentDateTime.getMinute();
int second = currentDateTime.getSecond();
|
获取星期
1
| DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
|
2.3 时间的计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
LocalDateTime currentDateTime = LocalDateTime.now(); LocalDateTime localDateTimePlusY1 = currentDateTime.plusYears(10); System.out.println("加10年: "+localDateTimePlusY1); LocalDateTime localDateTimePlusY2 = currentDateTime.minusYears(5); System.out.println("减5年: "+localDateTimePlusY2); LocalDateTime localDateTimePlusM1 = currentDateTime.plusMonths(2); System.out.println("加2月: "+localDateTimePlusM1); LocalDateTime localDateTimePlusM2 = currentDateTime.minusMonths(2); System.out.println("减2月: "+localDateTimePlusM2);
|
2.4 时间的修改
1 2 3 4 5 6 7 8 9 10 11
|
LocalDateTime ldt = currentDateTime.withYear(2018).withMonth(12).withDayOfMonth(30).withHour(12).withMinute(10).withSecond(59);
|
2.5 时间的转换
2.5.1 时间转字符串
1
| String llts = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
|
2.5.2 时间转时间戳
1
| long milli = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
第二章 Lambda表达式/函数式接口
第1节 Lambda表达式
1.1 Lambda表达式介绍
1 2 3
| 1. Lambda 表达式也可称为闭包,它是Java8发布的最重要新特性 2. Lambda 允许把函数作为一个方法的参数 3. Lambda 表达式可以使代码变的更加简洁紧凑
|
1.2 Lambda表达式语法
1 2 3
| (parameters) -> expression 或 (parameters) ->{ statements; }
|
1.3 Lambda表达式的演进
对于Java变量我们可以给其赋值(基本数据类型,引用数据类型)
如果想把”一块代码”赋给一个Java变量,应该怎么做呢?
在Java 8之前,这个是做不到的,但是Java8问世之后,利用Lambda特性,就可以做到了
上面的写法并不是一个很简洁的写法,为了让这个赋值更加优雅,我们可以移除一些多余的声明
这样,我们就成功的非常优雅的把”一块代码”赋给了一个变量,而”这块代码”,或者说”这个被赋给一个变量的函数”,就是一个Lambda表达式;但是这里仍然有一个问题,就是变量aBlockOfCode的类型应该是什么?
在Java8里面,所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是”那段代码”,需要是这个接口的实现.这是我认为理解Lambda的一个关键所在,简而言之就是,Lambda表达式本身就是一个接口的实现.直接这样说可能还是有点让人困扰,我们继续看看例子.我们给上面的aBlockOfCode加上一个类型
这种只有一个接口函数需要被实现的接口类型,我们叫它”函数式接口”.为了避免后来的人在这个接口中增加接口函数导致其有多个接口函数需要被实现,变成”非函数接口”,我们可以在这个上面加上一个声明@FunctionalInterface,这样别人就无法在里面添加新的接口函数了
这样,我们就得到了一个完整的Lambda表达式声明
1.4 Lambda表达式的作用
对比一下Lambda表达式和传统的Java对同一个接口的实现
这两种写法本质上是等价的.但是显然,Java8中的写法更加优雅简洁.并且,由于Lambda可以直接赋值给一个变量,我们就可以直接把Lambda作为参数传给函数,而传统的Java必须有明确的接口实现的定义,初始化才行
有些情况下,这个接口实现只需要用到一次.传统的Java7必须要求你定义一个”污染环境”的接口实现MyInterfaceImpl,而相较之下Java8的Lambda,就显得干净很多
1.5 Lambda表达式的简单使用
定义函数式接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /** * @WebSite : ukoko.cn * @Date : 2020/11/8 12:11 * @Description: 自定义函数式接口 */ @FunctionalInterface public interface MyLambdaInterface { //测试求a+b和 int testMethodAdd(int a,int b); }
函数式接口的特点: 1. 要是一个接口 2. 接口内有且只有一个抽象方法 3. 为了防止破坏函数式接口,最好是在接口上面使用@FunctionalInterface注解修饰
|
函数式接口的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| /** * @WebSite : ukoko.cn * @Date : 2020/11/8 12:08 * @Description : Lambda表达式简单使用 */ public class TestLambda { /** * 传统方式 */ @Test public void test01(){ //匿名内部类(或者是定义一个外部类来实现此接口,然后实例化外部类的方式) MyLambdaInterface myLambdaInterface = new MyLambdaInterface() { @Override public int testMethodAdd(int a, int b) { return a+b; } }; int methodAdd = myLambdaInterface.testMethodAdd(100, 200); System.out.println(methodAdd); } /** * Lambda表达式方式 */ @Test public void test02(){ //如果箭头右侧加大括号,不能去掉return关键字 MyLambdaInterface myLambdaInterface = (a,b)->{return a+b;}; int methodAdd = myLambdaInterface.testMethodAdd(200, 300); System.out.println(methodAdd); } }
|
1.6 Lambda在Java8中的应用
1
| Java8中对很多的API进行了修改,加入了函数式编程的语法
|
比如集合框架的修改
对一个集合中的数据进行排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Test public void test03(){ List<String> list = new ArrayList<>(); list.add("lilei"); list.add("hanmeimei"); list.add("jim"); list.add("tom"); System.out.println("排序前: "+list); Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); System.out.println("排序后: "+list); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void test04(){ List<String> list = new ArrayList<>(); list.add("lilei"); list.add("hanmeimei"); list.add("jim"); list.add("tom"); System.out.println("排序前: "+list); //使用Collections工具类进行排序(如果箭头右侧不加大括号,可以去掉return关键字) Collections.sort(list,(s1,s2)->s1.compareTo(s2)); System.out.println("排序后: "+list); }
|
第2节 函数式接口
2.1 函数式接口介绍
1 2 3
| 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
Java8中新增了很多的函数式接口在java.util.function包下,在其他包下也有函数式接口
|
2.2 常见的函数式接口
2.3 函数式接口使用(JDK8提供)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class TestFunctionInterface { @Test public void test01(){ /** * 接受两个输入参数的操作 * 没有返回值的函数式接口 */ BiConsumer<Integer,Integer> biConsumer = (a,b)-> System.out.println(a+b); biConsumer.accept(200,200); }
@Test public void test02(){ /** * 接受两个输入参数的操作 * 并且有返回值 */ BiFunction<Integer,Integer,Integer> biFunction = (x,y)-> x+y; Integer sum = biFunction.apply(10000, 20000); System.out.println("sum= "+sum); } }
|
第三章 默认方法/静态方法
第1节 默认方法
1.1 默认方法介绍
1 2 3
| 默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法 Java8之前接口里面的方法必须全部都是抽象方法,没有方法体 Java8之后接口中可以定义带有方法体的方法,但是需要在方法前加default关键字进行修饰
|
1.2 默认方法语法
1 2 3 4 5 6 7
| @FunctionalInterface public interface MyLambdaInterface { default int testDefaultMethod(int a,int b){ return a+b; } }
|
1.3 默认方法使用
1 2 3 4 5 6 7 8 9 10 11
|
@Test public void test05(){ MyLambdaInterface myLambdaInterface = (a,b)->a+b; int method1 = myLambdaInterface.testDefaultMethod(100, 300); System.out.println(method1); }
|
注意: 如果多个接口定义相同名称和类型的默认方法,因为接口的多实现特性可能会让子类中出现不知道该怎么调用父类接口中默认方法的问题,解决方案有两种,一种是在子类中创建自己的默认方法,覆盖原有的默认方法,第二种是使用父类名.super.方法名进行调用
第2节 静态方法
2.1 静态方法介绍
1
| 静态方法和默认方法差不多,就是将default修饰符修改成statis
|
2.2 静态方法语法
1 2 3 4 5 6 7
| @FunctionalInterface public interface MyLambdaInterface { static int testStaticMethod(int a,int b){ return a+b; } }
|
2.3 静态方法使用
1 2 3 4 5 6
| @Test public void test05(){ int method = MyLambdaInterface.testStaticMethod(1000, 2000); System.out.println(method); }
|
第四章 方法引用
第1节 方法引用介绍
1 2 3 4 5 6 7 8 9 10 11
| 我们在说方法引用前,先说一下Lambda表达式的组成 (a,b)->{return a+b;} 或者 (a,b)-> a+b;
左侧的括号: 函数式接口里面定义的抽象方法的形参列表 箭头: Lambda表达式的操作符,看见这个箭头,就可以认为他是一个Lambda表达式 右侧Lambda体: 函数式接口中,我们实现了函数式接口抽象方法的方法体
对于右侧的Lambda体,可以是一个自定义的表达式(比如上面的a+b) 或者是仅仅调用一个已经存在的方法,这种情况下,可以使用方法引用的方式调用这个已经存在的方法.方法引用的操作符(::)两个冒号.
|
第2节 方法引用的语法分类
类型 |
语法 |
对应的Lambda表达式 |
类静态方法引用 |
类名::staticMethod |
(args) -> 类名.staticMethod(args) |
实例方法引用 |
inst::instMethod |
(args) -> inst.instMethod(args) |
类普通方法引用 |
类名::instMethod |
(inst,args) -> 类名.instMethod(args) |
构造方法引用 |
类名::new |
(args) -> new 类名(args) |
第3节 引用的使用
3.1 静态方法引用
静态方法介绍
1
| Lambda表达式中调用某个类的静态方法,且Lambda表达式的参数作为静态方法的入参传入,最后Lambda的方法返回类型要和静态方法的返回类型对上.
|
代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@Test public void test01(){ Function<String,Integer> function=x->Integer.parseInt(x); Integer apply = function.apply("100"); System.out.println(apply);
Function<String,Integer> fun = Integer::parseInt; Integer apply1 = fun.apply("300"); System.out.println(apply1);
}
|
3.2 实例方法引用
实例方法介绍
1
| Lambda表达式中调用某个类的对象的实例方法,且Lambda表达式的参数作为方法的入参传入,最后Lambda的方法返回类型要和实例方法的返回类型对上
|
代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class A{ int sum(int a,int b){ return a+b; } }
@FunctionalInterface interface B{ int count(int a,int b); }
@Test public void test02(){ A a = new A(); B b1 = (x,y)->x+y; System.out.println(b1.count(1,100)); B b2 = a::sum; System.out.println(b2.count(2,200)); }
|
3.3 类普通方法引用
类普通方法介绍
1
| Lambda表达式中调用Lambda形参中第一个参数的某个实例方法,并且Lambda形参剩余的n-1个参数作为这个实例方法的实参.Lambda的方法返回类型要和对象的实例方法的返回类型对应.
|
代码演示
1 2 3 4 5 6 7 8 9
| @Test public void test03(){ Function<String,String> fun1 = (x)->x.toUpperCase(); System.out.println(fun1.apply("abcdefg")); Function<String,String> fun2 = String::toUpperCase; System.out.println(fun2.apply("hijklmn")); }
|
3.4 构造方法引用
构造方法介绍
1
| Lambda的形参作为某个类的构造方法/方法的实参
|
代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class User{ private Integer userId; private String userName;
public static User createUser(Supplier<User> supplier){ return supplier.get(); } }
@Test public void test04(){ User user1 = User.createUser(()->{return new User();}); user1.setUserId(1001); user1.setUserName("李雷"); User user2 = User.createUser(User::new); user2.setUserId(2001); user2.setUserName("韩梅梅"); System.out.println(user1); System.out.println(user2); }
|
第五章 Stream API
第1节 Stream API介绍
1.1 Stream是什么?
1 2 3 4
| Stream API是Java8中加入的一套新的API,主要用于处理一组数据的操作 它的处理方式与传统的方式不同,称为"数据流处理" 就是将集合/数组/文件/函数等数据转换成流之后再处理(比如对集合数据进行过滤,排序等操作) Stream并不是数据结构所以不能保存数据,主要目的在于计算
|
1.2 简述Stream优势
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class User{ private Integer userId; private String userName; private Integer age; private Integer classId; }
List<User> users = new ArrayList<>();
for (User user : users) { if(user.getAge()<18){ System.out.println("JDK7 >>>年纪小于18的用户为: "+user); } }
Stream<User> userStream = users.stream();
List<User> userList = userStream.filter(x -> x.getAge() < 18).sorted((x,y)->y.getClassId().compareTo(x.getClassId())).collect(Collectors.toList()); System.out.println("JDK8 >>>年纪小于18的用户为: "+userList);
|
第2节 Stream API使用
2.1 生成Stream的方式
通过集合生成Stream
1 2
| List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); Stream<Integer> stream1 = list.stream();
|
通过数组生成Stream
1 2
| int[] arr = new int[]{1,2,3,4,5,6,7,8,9,0}; IntStream stream2 = Arrays.stream(arr);
|
通过值生成Stream
1
| Stream<Integer> stream3 = Stream.of(100, 200, 150, 210, 105);
|
通过文件生成Stream
1
| Stream<String> stream4=Files.lines(Paths.get("stream.txt"),Charset.defaultCharset());
|
通过函数生成Stream
iterator
1 2
| Stream<Integer> stream5 = Stream.iterate(0, n -> n + 2).limit(5);
|
generator
1 2
| Stream<Double> stream6 = Stream.generate(Math::random).limit(5);
|
2.2 Stream的使用
1 2 3
| 流的操作类型主要分为两种: 1. 中间操作 2. 终端操作
|
2.2.1 中间操作
一个流可以后面跟随零个或多个中间操作,目的是打开流,做出将要对数据进行某种操作的指示,然后返回一个新流,交给下一个操作使用.这种操作是惰性的,仅仅调用了这个类的方法,并不会进行具体的操作,真正操作需等到终端操作
2.2.1.1 filter筛选
1 2 3 4 5 6 7 8 9 10
| @Test public void test01(){ List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); List<Integer> collect = stream.filter(x -> x > 3).collect(Collectors.toList()); System.out.println("原数据:"+integers); System.out.println("筛选之后的数据:"+collect); }
|
2.2.1.2 distinct去除重复元素
1 2 3 4 5 6 7 8 9 10
| @Test public void test02(){ List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); List<Integer> collect = stream.distinct().collect(Collectors.toList()); System.out.println("原数据:"+integers); System.out.println("去重之后的数据:"+collect); }
|
2.2.1.3 limit返回指定流个数
1 2 3 4 5 6 7 8 9 10
| @Test public void test03(){ List<Integer> integers = Arrays.asList(1,2,2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); List<Integer> collect = stream.limit(5).collect(Collectors.toList()); System.out.println("原数据:"+integers); System.out.println("目标数据:"+collect); }
|
2.2.1.4 skip跳过流中的元素
1 2 3 4 5 6 7 8 9 10
| @Test public void test04(){ List<Integer> integers = Arrays.asList(1,2,2,3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); List<Integer> collect = stream.skip(10).collect(Collectors.toList()); System.out.println("原数据:"+integers); System.out.println("目标数据:"+collect); }
|
2.2.1.5 map流映射
1 2 3 4 5 6 7 8 9 10
| @Test public void test05(){ List<Integer> integers = Arrays.asList(1,2,2,3); Stream<Integer> stream = integers.stream(); List<String> collect = stream.map(x -> x.toString()).collect(Collectors.toList()); System.out.println("原数据:"+integers); System.out.println("目标数据:"+collect); }
|
2.2.1.6 flatMap流转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void test06(){ List<String> strings = Arrays.asList("H e l l o", "Java8"); Stream<String> stream = strings.stream();
List<String> collect = stream.map(x -> x.split(" ")).flatMap(Arrays::stream).collect(Collectors.toList()); System.out.println("原数据:"+strings); System.out.println("目标数据:"+collect); }
|
2.2.1.7 元素匹配
提供了三种匹配方式
- allMatch匹配所有
- anyMatch匹配其中一个
- noneMatch全部不匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Test public void test07(){ List<Integer> integers = Arrays.asList(1,2,3);
if(integers.stream().allMatch(x -> x > 3)){ System.out.println("全部大于3"); } if(integers.stream().anyMatch(x -> x > 3)){ System.out.println("存在大于3的数"); } if(integers.stream().noneMatch(x -> x > 3)){ System.out.println("全部小于等于3"); } }
|
2.2.2 终端操作
2.2.2.1 统计流中元素个数
1 2 3 4 5 6 7 8 9
| @Test public void test01(){ List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); long count = stream.count(); System.out.println("count:"+count); }
|
2.2.2.2 查找
findFirst查找第一个
findAny随机查找一个
1 2 3 4 5 6 7 8 9 10 11
| @Test public void test02(){ List<Integer> integers = Arrays.asList(100,1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 65, 5); Stream<Integer> stream = integers.stream(); Optional<Integer> any = stream.findAny(); System.out.println("any:"+any.get()); }
|
2.2.2.3 reduce将流中的元素组合起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Test public void test03(){ List<Integer> integers = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = integers.stream();
Integer reduce = stream.reduce(0, Integer::sum); System.out.println(reduce); }
|
2.2.2.4 获取流中最小最大值
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void test04(){ List<Integer> integers = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = integers.stream(); Optional<Integer> max = stream.max(Integer::compareTo); System.out.println(max.get()); }
|
2.2.2.4 求和
1 2 3 4 5 6 7 8 9
| @Test public void test05(){ List<Integer> integers = Arrays.asList(1,2,3,4,5); Stream<Integer> stream = integers.stream(); int sum = stream.mapToInt(x -> x).sum(); System.out.println(sum); }
|
2.2.2.5 通过averagingInt求平均值
1 2 3 4 5 6 7 8 9
| @Test public void test06(){ List<Integer> integers = Arrays.asList(1,2,3,4,5,10); Stream<Integer> stream = integers.stream(); Double collect = stream.collect(Collectors.averagingInt(Integer::intValue)); System.out.println(collect); }
|
2.2.2.6 通过summarizingInt同时求总和、平均值、最大值、最小值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void test07(){ List<Integer> integers = Arrays.asList(1,2,3,4,5,10); Stream<Integer> stream = integers.stream(); IntSummaryStatistics collect = stream.collect(Collectors.summarizingInt(Integer::intValue)); double average = collect.getAverage(); int min = collect.getMin(); int max = collect.getMax(); System.out.println(average); System.out.println(min); System.out.println(max); }
|
2.2.2.7 通过foreach进行元素遍历
1 2 3 4 5 6 7 8
| @Test public void test08(){ List<Integer> integers = Arrays.asList(1,2,3,4,5,10); Stream<Integer> stream = integers.stream(); stream.forEach(System.out::println); }
|
2.2.2.8 返回集合
1 2 3 4 5 6 7 8 9 10
| @Test public void test09(){ List<Integer> integers = Arrays.asList(1,2,3,4,5,10); Stream<Integer> stream = integers.stream(); List<Integer> collect = stream.collect(Collectors.toList()); System.out.println(collect); }
|
2.2.2.9 通过joining拼接流中的元素
1 2 3 4 5 6 7 8
| @Test public void test10(){ List<String> strings = Arrays.asList("Hello","Java8"); Stream<String> stream = strings.stream(); String collect = stream.map(s -> s.toString()).collect(Collectors.joining("-")); System.out.println(collect); }
|
2.2.2.10 通过groupingBy进行分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class User{ private Integer userId; private String userName; private int age; }
@Test public void test11(){ List<User> users = Arrays.asList(new User(1001, "李雷", 18), new User(1002, "李雷2", 18), new User(1003, "李雷3", 19), new User(1004, "李雷4", 19)); Stream<User> stream = users.stream(); Map<Integer, List<User>> collect = stream.collect(Collectors.groupingBy(User::getAge)); System.out.println(collect); }
|