Java8新增的特性之方法引用:
/*定义测试结构:*/public final class Student {
private String name;
private Integer age;
private Sex sex;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Sex getSex() {
return sex;
}
public Student(String name, Integer age, Sex sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public Student(String name) {
this.name = name;
}
public static void show(Student a){
System.out.println(a. toString ());
}
@Override
public String toString() {
return "Student{" + "name='" + name + ''' + ", age=" + age + ", sex=" + sex + '}';
}
public static Student of(String name,Integer age,Sex sex){
return new Student(name,age,sex);
}
public enum Sex{
MALE,FEMALE
}
}
public final class Teacher {
private List<Student> students;
private String name;
public List<Student> getStudents() {
return students;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Teacher{" + "students=" + students + ", name='" + name + ''' + '}';
}
public Teacher(String name) {
this.name = name;
this.students = new ArrayList<>();
}
public static Teacher of(String name){
return new Teacher(name);
}
public void addStudent(Student student){
this.students.add(student);
}
}
/*初始化测试数据*/Student [] students = new Student[]{
Student.of("Julia",20, Student.Sex.FEMALE),
Student.of("Lucy",18, Student.Sex.FEMALE),
Student.of("Tenli",22, Student.Sex.MALE),
Student.of("Keliys",34, Student.Sex.MALE)};
- Reference to a static methodContaining => Class::staticMethodName
/*静态方法引用:它的语法是Class::static_method,实例如下:*/Arrays. Stream (students).forEach(Student::show);
/*outputs:
* Student{name='Julia', age=20, sex=FEMALE}
* Student{name='Lucy', age=18, sex=FEMALE}
* Student{name='Tenli', age=22, sex=MALE}
* Student{name='Keliys', age=34, sex=MALE}
* */
- Reference to an instance method of a particular => objectcontainingObject::instanceMethodName
/*任意类的实例方法引用:它的语法是Class::method实例如下:*/Arrays.stream(students).sorted(Comparator.comparing(Student::getAge)).forEach(Student::show); /*outputs: * Student{name='Lucy', age=18, sex=FEMALE} * Student{name='Julia', age=20, sex=FEMALE} * Student{name='Tenli', age=22, sex=MALE} * Student{name='Keliys', age=34, sex=MALE} * */
- Reference to an instance method of an arbitrary object of a particular type => ContainingType::methodName
/*特定对象的方法引用:它的语法是instance::method实例如下:*/Teacher teacher = Teacher.of("Teach Li"); Arrays.stream(students).forEach(teacher::addStudent); out(teacher.toString());br(); /*outputs: * Teacher{students=[ * Student{name='Julia', age=20, sex=FEMALE}, * Student{name='Lucy', age=18, sex=FEMALE}, * Student{name='Tenli', age=22, sex=MALE}, * Student{name='Keliys', age=34, sex=MALE}], * name='Teach Li'} * */
- Reference to a constructor => ClassName::new
/*构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下*/String [] names = {"Kafka"," Express ","Node","Lua"};
Arrays.stream(names).map(Teacher::new).forEach(t->out(t.toString()));
/*outputs:
* Teacher{students=[], name='Kafka'}
* Teacher{students=[], name='Express'}
* Teacher{students=[], name='Node'}
* Teacher{students=[], name='Lua'}
* */
Java8 Stream API
Java 8 新增的 Stream,可以让你以一种声明的方式处理数据。
这种风格将要处理的元素集合看作一种流, 流数据在管道中传输, 在管道的各个节点上进行处理, 如筛选, 排序, 转换,聚合等。元素流在管道中经过`中间操作`的处理,最后由`最终操作`得到前面处理的结果.
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
Java中的Stream并不会存储元素,而是按需处理。
数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
Pipelining : 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代 : 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
在 Java 8 中, 集合接口有两个方法来生成流:
stream() − 为集合创建串行流。
parallelStream() − 为集合创建并行流,parallelStream 是流并行处理程序的代替方法。
下面我们主要来看看串行流的用法,并行流和串行流主要的区别就在于[并行],但是要注意使用场景,并非所有串行流的使用场景都可以用并行流来代替.
/** * 先来构建一波测试数据 * TestData * 测试数据,使用的初始化方式快捷但是在实际开发中不推荐哦. * * @since 2019年09月02日 20:02 */public final class TestData { // 初始化一个不可变List<Integer> static List<Integer> INTEGERS = Arrays.asList(1, 2, 3, 4, 5, 5); // 初始化一个可变List<Integer> static List<Integer> LIST_INTEGERS = new ArrayList<>(INTEGERS); // 初始化一个可变Set<Integer> static Set<Integer> SET_INTEGERS = new HashSet<>(INTEGERS); // 快速初始化List<String> static List<String> STRINGS = new ArrayList<String>() { private static final long serialVersionUID = 1L; { add("abc"); add("bca"); add("acb"); } }; // 另类快速初始化一个Map<String,Integer> static Map<String, Integer> AGES = new HashMap<String, Integer>() { private static final long serialVersionUID = 1L; { put("HP", 12); put("ASUS", 15); put("HuaWei", 22); } }; // 另类快速初始化一个List<Map<String,Integer>> static List<Map<String, Integer>> STR_AGES = new ArrayList<Map<String, Integer>>() { { add(new HashMap<String, Integer>() { { put("HP", 12); put("ASUS", 15); put("HuaWei", 22); } }); add(new HashMap<String, Integer>() { { put("HP", 22); put("ASUS", 35); put("HuaWei", 42); } }); add(new HashMap<String, Integer>() { { put("HP", 11); put("ASUS", 25); put("HuaWei", 32); } }); } }; private TestData() { } } /*测试几个主要的流操作(头条文章里代码编辑支持不是很好,显示出来可读性有些不好,下面用图片展示)*/
Java8 的 Stream让Collections的操作管道化,对集合数据的操作趋向于流水线处理,编码过程更如行云流水般畅快.
同时,我们也要注意在不同场景下的Stream操作和常规的Loop操作的区别和优劣,学以致用,但绝不滥用.