类名::实例方法名 (比较不好理解,个地方调用的方法只有一个参数,为什么还能正常调用呢? 因为调用比较时,第一个对象来调用getStudentByScore1. 第二个对象来当做参数)
构造方法引用: 类名::new
public class StudentTest { public static void main(String[] args) { Student student = new Student("zhangsan",10); Student student1 = new Student("lisi",40); Student student2 = new Student("wangwu",30); Student student3 = new Student("zhaoliu",550); List<Student> list = Arrays.asList(student, student2, student3, student1); // list.forEach(item -> System.out.println(item.getName())); //1. 类名 :: 静态方法 // list.sort((studentpar1,studentpar2) -> Student.getStudentByScore(studentpar1,studentpar2)); list.sort(Student::getStudentByScore); list.forEach(item -> System.out.println(item.getScore())); System.out.println(" - - - - - - - -- "); // 2. 引用名(对象名)::实例方法名 StudentMethod studentMethod = new StudentMethod(); list.sort(studentMethod::getStudentBySource); list.forEach(item -> System.out.println(item.getScore())); System.out.println(" - - - -- -- "); // 3. 类名:: 实例方法名 // 这个地方调用的方法只有一个参数,为什么还能正常调用呢? 因为调用比较时,第一个对象来调用getStudentByScore1. 第二个对象来当做参数 list.sort(Student::getStudentByScore1); list.forEach(item -> System.out.println(item.getScore())); System.out.println("- - - - - - - -"); // 原生的sort 来举个例子 List<String> list1 = Arrays.asList("da", "era", "a"); // Collections.sort(list1,(city1,city2) -> city1.compareToIgnoreCase(city2)); list1.sort(String::compareToIgnoreCase); list1.forEach(System.out::println); System.out.println("- - - - - - -- "); //4. 构造方法引用 StudentTest studentTest = new StudentTest(); System.out.println(studentTest.getString(String::new)); } public String getString(Supplier<String> supplier) { return supplier.get()+"hello"; } } 默认方法defaute method
默认方法是指实现此接口时,默认方法已经被默认实现。
引入默认方法最重要的作用就是Java要保证向后兼容。
情景一: 一个类,实现了两个接口。两个接口中有一个相同名字的默认方法。此时会报错,需要从写这个重名的方法
情景二: 约定:实现类的优先级比接口的优先级要高。 一个类,实现一个接口,继承一个实现类。接口和实现类中有一个同名的方法,此时,此类会使用实现类中的方法。
Stream 流介绍和操作方式详解Collection提供了新的stream()方法。
流不存储值,通过管道的方式获取值。
本质是函数式的,对流的操作会生成一个结果,不过并不会修改底层的数据源,集合可以作为流的底层数据源。
延迟查找,很多流操作(过滤、映射、排序等)等可以延迟实现。
通过流的方式可以更好的操作集合。使用函数式编程更为流程。与lambda表达式搭配使用。
流由3部分构成:源
零个或多个中间操作(操作的是谁?操作的是源)
终止操作(得到一个结果)
流操作的分类:惰性求值(中间操作)
及早求值(种植操作)
使用链式的调用方式sunc as : stream.xxx().yyy().zzz().count(); 没有count的时候前边的三个方法不会被调用。后续会进行举例。
掌握流常用的api,了解底层。
流支持并行化,可以多线程操作。迭代器不支持并行化。
流怎么用? 流的创建方式通过静态方法 : Stream stream = Stream.of();
通过数组:Arrays.stream();
通过集合创建对象:Stream stream = list.stream;
流的简单应用 public static void main(String[] args) { IntStream.of(1,2,4,5,6).forEach(System.out::println); IntStream.range(3, 8).forEach(System.out::println); IntStream.rangeClosed(3, 8).forEach(System.out::println); } 举例:将一个数组中的数字都乘以二,然后求和。 public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); System.out.println(list.stream().map(i -> i*2).reduce(0,Integer::sum)); }函数式编程和传统面向对象编程根本上有什么不同?
传统面向对象编程传递的是数据。函数式编程通过方法传递的是一种行为,行为指导了函数的处理,根据行为对数据进行加工。
举例:流转换成list的练习 public static void main(String[] args) { Stream<String> stream = Stream.of("hello", "world", "hello world"); // String[] stringArray = stream.toArray(length -> new String[length]); //替换成方法引用的方式 --> 构造方法引用. String[] stringArray = stream.toArray(String[]::new); Arrays.asList(stringArray).forEach(System.out::println); System.out.println("- - - - - - - - - - -"); //将流转换成list, 有现成的封装好的方法 Stream<String> stream1 = Stream.of("hello", "world", "hello world"); List<String> collect = stream1.collect(Collectors.toList());// 本身是一个终止操作 collect.forEach(System.out::println); System.out.println("- - - - - - "); //使用原生的 collect 来将流转成List Stream<String> stream2 = Stream.of("hello", "world", "hello world"); // List<String> lis = stream2.collect(() -> new ArrayList(), (theList, item) -> theList.add(item), // (theList1, theList2) -> theList1.addAll(theList2)); // 将上面的转换成方法引用的方式 -- 这种方法不好理解. List<String> list = stream2.collect(LinkedList::new, LinkedList::add, LinkedList::addAll); //这种方法,如果想要返回ArrayList也可以实现. // List<String> list1 = stream2.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); list.forEach(System.out::println); } Collectors类中包含了流转换的多个辅助类 举例: 将流 转成各种类型的数据。 public static void main(String[] args) { Stream<String> stream = Stream.of("hello", "world", "hello world"); //将流转换成List 另一种方法 // List<String> list= stream.collect(Collectors.toCollection(ArrayList::new)); // list.forEach(System.out::println); //将流转成set // Set<String> set = stream.collect(Collectors.toSet()); //转成TreeSet // TreeSet<String> set = stream.collect(Collectors.toCollection(TreeSet::new)); // set.forEach(System.out::println); //转成字符串 String string = stream.collect(Collectors.joining()); System.out.println(string); //Collectors 类中有多重辅助的方法. }