前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

java8

作者头像
如来
发布2020-07-14 15:29:34
7930
发布2020-07-14 15:29:34
举报
文章被收录于专栏:如来的java学习如来的java学习

Day1:


1. Lambda表达式

  • Lambda表达式的基本结构: (param1,param2,param3,paramN) ->{body}
  • 关于函数式接口:
  1. 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
  2. 如果我们在某个接口上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来要求该接口。
  3. 如果某个接口只有一个抽象方法,但我们没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看作是函数式接口。 ps(为什么函数式接口中只有一个抽象方法:因为在Lambad表达式中并没有指定方法名字(所以函数式接口中的方法只能有一个)) 在java中Lambad表示式是对象,他们必须依附于一类特别的对象函数——函数式接口(functional interface)
代码语言:javascript
复制
test2.myTest(()-> {
            System.out.println("MyInterface");
        });
代码语言:javascript
复制
//method reference(方法引用)
list.forEach(System.out::println);
代码语言:javascript
复制
List<String> list = Arrays.asList("nihao", "xiaoming");
        list.forEach(item -> System.out.println(item.toUpperCase()));
        List<String> list1 = new ArrayList<>();
        list.forEach(item -> list1.add(item.toUpperCase()));
        list.stream().map(item ->item.toUpperCase()).forEach(item -> System.out.println(item));
        list.stream().map(String::toUpperCase).forEach(item-> System.out.println(item));

运行结果

代码语言:javascript
复制
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\lib\idea_rt.jar=59655:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;C:\Users\user\ideaTest\java8\target\classes" com.mobius.vision.jdk8.Test3
NIHAO
XIAOMING
NIHAO
XIAOMING
NIHAO
XIAOMING

Lamdba表达式的作用:

  • 传递行为,而不仅仅是值。
  • 提升抽象层次
  • API重用性更好
  • 更加灵活

Java Lambda结构

  • 一个Lambda表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同。
  • 空圆括号代表参数集为空。例如:()->42
  • (args1,args2....)->{body} Lambda表达式的语法
代码语言:javascript
复制
System.out.println(functionTest.addThe(1,2,(value1,value2)->value1+value2,value3->value3*value3));
        //先将1和2作为参数给biFunction:1+2得3然后将3作为参数给function3*3得9
    }
    public Integer addThe(int a,int b,BiFunction<Integer,Integer,Integer> biFunction,
                          Function<Integer,Integer> function){
        return biFunction.andThen(function).apply(a,b);
    }

Lambda表达式的一些操作

代码语言:javascript
复制
package com.mobius.vision.jdk8;

import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

/**
 * @author NingXioaoming
 * @createTime 2019/11/8 11:05
 * @description
 */
public class Test4 {
    public static void main(String[] args) {
        Person person = new Person();
        person.setUserName("zhangsan");
        person.setAge(18);
        Person person1 = new Person();
        person1.setUserName("lisi");
        person1.setAge(20);
        Person person2 = new Person();
        person2.setUserName("wangwu");
        person2.setAge(22);
        List<Person> list = Arrays.asList(person, person1, person2);

        Test4 test4 = new Test4();
        List<Person> persons = test4.getPersonsByUsername("zhangsan", list);
        persons.forEach(pp-> System.out.println(pp.getUserName()));

        List<Person> personsByUsername = test4.getPersonsByUsername(20, list);
        personsByUsername.forEach(user-> System.out.println(user.getAge()));

        List<Person> personsByT = test4.getPersonsByT(19, list, (age, list1) ->
                list1.stream().filter(person3 -> person3.getAge() > age).collect(Collectors.toList())
        );
        personsByT.forEach(person3 -> System.out.println(person3.getAge()));
    }
    public List<Person> getPersonsByT(Integer age,List<Person> list,BiFunction<Integer,List<Person>,List<Person>> biFunction){
        return biFunction.apply(age,list);
    }
    public List<Person> getPersonsByUsername(String userName, List<Person> list){
        list.forEach(person -> System.out.println(person.getUserName()));
        return list.stream().filter(person1 -> person1.getUserName().equals(userName)).collect(Collectors.toList());
    }
    public List<Person> getPersonsByUsername(Integer age,List<Person> list){
        BiFunction<Integer,List<Person>,List<Person>> biFunction =(age1,personList)->
             personList.stream().filter(person -> person.getAge()>age).collect(Collectors.toList());
        return biFunction.apply(age,list);
    }
}

Day2:


1. Optional

optional的一些使用方法

代码语言:javascript
复制
        Optional<String> heloo = Optional.of("1111");//一定不为空
        Optional<String> heloo1 = Optional.empty();//一定为空
        Optional<String> heloo2 = Optional.ofNullable("1111");//不确定是否为空
        heloo.ifPresent(item -> System.out.println(item));

判断person是否为空方法

代码语言:javascript
复制
        List<String> list = Arrays.asList("nihapo", "wohap");
        List<String> list1 = Arrays.asList();
        Person person = new Person();
        person.setList(list1);
        Optional<Person> optional = Optional.ofNullable(person);
        //判断person是否为空方法
        System.out.println(optional.map(thePerson->thePerson.getList()).orElse(Collections.emptyList()));

方法引用

  • 方法引用:method reference
  • 方法引用实际上是个Lambda表达式的一种语法糖
  • 我们可以将方法引用看做是一个【函数指针】,function pointer,
  • 方法引用共分为4类
    1. 类名::静态方法名。
    2. 引用名(对象名)::实类方法名。
    3. 类名::示例方法名。
    4. 构造方法引用:类名::new
代码语言:javascript
复制
Student student1 = new Student("zhangsan", 18);
        Student student2 = new Student("lisi", 20);
        Student student3 = new Student("wangwo", 22);
        Student student4 = new Student("xuebing", 16);
        List<Student> list = Arrays.asList(student1, student2, student3, student4);
        list.sort((studentParam1,studentParam2)->Student.compareStudentByScore(studentParam1,studentParam2));
        //上下这两个排序等价,下面是上面的方法糖
        //1. 类名::静态方法名
        list.sort(Student::compareStudentByScore);
        list.forEach(student -> System.out.println(student.getScore()));
        //2.引用名(对象名)::实类方法名。
        StudentCompare studentCompare = new StudentCompare();
        list.sort(studentCompare::compareByScore);
        list.forEach(student -> System.out.println(student.getScore()));
        //3.类名::示例方法名。
        list.sort(Student::compareByScore);
        //4.构造方法引用:类名::new

Stream(流)

  • 流由3部分构成:
    1. 零个或多个中间操作:中间操作都会返回一个Stream对象,例如:Stream<Student>,Stream<Integer>。
    2. 终止操作:终止操作则不会返回Stream类型,可能不返回值,也可能返回其他类型的单个值。
  • 流操作的分类:
    1. 惰性求值
    2. 及早求值
代码语言:javascript
复制
        List<Integer> list = Arrays.asList(2, 4, 5, 6, 8);
        list.stream().map(i->i*2).forEach(integer -> System.out.println(integer));
        //给list中的每一个元素*2然后再相加操作
        //这是一个流:list是源,map是中间操作,reduce是终止操作
        System.out.println(list.stream().map(i -> i*2).reduce(0,Integer::sum));

Stream(流)的一些操作

代码语言:javascript
复制
 //一个流只能被操作一次 多次操作编译报错:Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
        Stream<String> stream = Stream.of("hello","nihap");
//        String[] strings = stream.toArray(length -> new String[length]);
        //等价于上面   这里使用方法引用
//        String[] strings1 = stream.toArray(String[]::new);
        //将stream转化成list集合
        List<String> collect = stream.collect(Collectors.toList());
        collect.forEach(System.out::println);

        Stream<String> stream1 = Stream.of("hello","nihap","word");
//        List<String> collect1 = stream1.collect(Collectors.toList());
        ArrayList<String> collect1 = stream1.collect(() -> new ArrayList(), (theList, iteam) -> theList.add(iteam), (theList1, theList2) -> theList1.addAll(theList2));
        //下面的方法引用等价于上面的lambda表达式
        stream1.collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
        collect1.forEach(item-> System.out.println(item));
        //将流转化成LinkedHashSet以及其他....
        LinkedHashSet<String> collect2 = stream2.collect(Collectors.toCollection(LinkedHashSet::new));
        //将流对象转化成String
        String collect3 = stream2.collect(Collectors.joining());
        //将集合中的元素转化成大写并输出Map给一个元素对这个元素操作(加减乘除等...)之后返回一个新的元素
        list.stream().map(String::toUpperCase).collect(Collectors.toList()).forEach(item-> System.out.println(item));
        Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1, 2), Arrays.asList(2, 3), Arrays.asList(4, 5));
        //flatMap的用法:将多个集合组成的流压成一个流
        listStream.flatMap(theList->theList.stream()).map(item->item*item).forEach(integer -> System.out.println(integer));
        //通过Stream的generate静态方法生成Stream对象,然后输出Stream流中的第一个元素
        Stream<String> stream1 = Stream.generate(UUID.randomUUID()::toString);
        stream1.findFirst().ifPresent(System.out::println);
        //构造88个偶数放到Stream流中然后输出2,4,8,16    n+1=n*n
        Stream.iterate(2,item->item*2).limit(88).forEach(System.out::println);
        Stream<Integer> stream3 = Stream.iterate(1, item -> item + 2).limit(6);
        //取出stream3中的大于2的元素,每一个乘以二,然后再提出前两个元素,然后再取出前两元素,然后去掉重复元素,然后再相加
        System.out.println(stream3.filter(itemIn -> itemIn > 2).mapToInt(item -> item * 2).skip(2).limit(2).distinct().sum());
        //Stream.summaryStatistics();返回IntSummaryStatistics对象包含了一些数字的结果(max,min,count。。。。)
        IntSummaryStatistics intSummaryStatistics = stream3.filter(itemIn -> itemIn > 2).mapToInt(item -> item * 2).skip(2).limit(2).distinct().summaryStatistics();
        System.out.println(intSummaryStatistics.getMax());
        System.out.println(intSummaryStatistics.getMin());
        System.out.println(intSummaryStatistics.getSum());
        System.out.println(intSummaryStatistics.getCount());
  • 内部迭代:将n个条件拼接,然后进行循环查找。 flatMap的用法
代码语言:javascript
复制
        List<String> list1 = Arrays.asList("hello ww", "hello ee", "qq hello");
        //flatMap:将多个stream打平放到一个stream中     (单词去重)
        list1.stream().map(item->item.split(" ")).flatMap(Arrays::stream).distinct().collect(Collectors.toList()).forEach(System.out::println);

分组和分区的操作

代码语言:javascript
复制
        List<Student> students = Arrays.asList(student, student1, student2, student3);
        //根据Student的name进行分组类似sql的group by
        Map<String, List<Student>> map = students.stream().collect(Collectors.groupingBy(Student::getName));
        Map<Integer, List<Student>> map1 = students.stream().collect(Collectors.groupingBy(Student::getScore));
        Map<String, Long> collect = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()));
        Map<String, Double> collect1 = students.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingInt(Student::getScore)));
        //对数据分区
        Map<Boolean, List<Student>> collect2 = students.stream().collect(Collectors.partitioningBy(student7 -> student7.getScore() > 80));

collect方法的详细介绍:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Day1:
    • 1. Lambda表达式
      • Lamdba表达式的作用:
      • Java Lambda结构
  • Day2:
    • 1. Optional
      • 方法引用
      • Stream(流)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档