Java函数式编程之Stream流操作
函数式编程是个好东西,一串就能代替一大坨,使用函数式编程十分清晰明了,简洁明快,代码干净整齐,后期也利于代码的维护,尤其是对于内存对象集合操作这方面,函数式编程简直是神器一样的存在。而Stream则是Java函数编程中的典范工具。Stream在日常业务数据操作方面应用十分广泛,经典的场景之一就是在内存中对数据对象集合进行查询筛选规约计算!
文章目录
1. 准备对象集合数据
操作实例对象集合之前,我们要先准备"米",也就是数据集合,待会儿操作用。弄个很简单的Student类吧。
class Student {
String name;
int age;
Date birthday;
float height;
double weight;
public String getName() { return name; }
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
public Date getBirthday() {return birthday;}
public void setBirthday(Date birthday) {this.birthday = birthday;}
public float getHeight() {return height;}
public void setHeight(float height) {this.height = height;}
public double getWeight() {return weight;}
public void setWeight(double weight) {this.weight = weight;}
public Student() {}
public Student(String name, int age, Date birthday, float height, double weight) {
this.name = name;
this.age = age;
this.birthday = birthday;
this.height = height;
this.weight = weight;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", height=" + height +
", weight=" + weight +
'}';
}
}
然后攒一些强类型对象集合
List<Student> students = new LinkedList<>();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
students.add(new Student("小红",18, dateFormat.parse("1999-02-01 00:12:15"),160.2f,66.53));
students.add(new Student("小明",19, dateFormat.parse("1997-02-01 00:12:15"),170.2f,67.53));
students.add(new Student("小志",20, dateFormat.parse("1989-02-01 00:12:15"),181.2f,64.53));
students.add(new Student("小王",22, dateFormat.parse("1988-02-01 00:12:15"),166.2f,68.53));
students.add(new Student("小李",30, dateFormat.parse("1992-02-01 00:12:15"),155.2f,67.53));
students.add(new Student("老赵",28, dateFormat.parse("1995-02-01 00:12:15"),167.2f,69.53));
students.add(new Student("老孙",19, dateFormat.parse("1994-02-01 00:12:15"),154.2f,50.53));
2. sorted排序操作
// 排序-按年龄升序
List<Student> studentsSortByAge = students.stream()
.sorted(Comparator.comparing(Student::getAge))
.collect(Collectors.toList());
studentsSortByAge.stream()
.sorted(Comparator.comparing(Student::getHeight))
.collect(Collectors.toList())
.forEach(System.out::println);
// 降序-按年龄降序
students.stream()
.sorted(Comparator.comparing(Student::getAge).reversed())
.collect(Collectors.toList())
.forEach(s->System.out.println(s));
// 先按年龄降序-再按身高升序
List<Student> studentsSortByAgeThenHeight = students.stream()
.sorted(Comparator.comparing(Student::getAge).reversed()
.thenComparing(Student::getHeight))
.collect(Collectors.toList());
3. map转化数字类型
//mapToLong、mapToDouble、mapToInt
Stream.of("apple", "banana", "orange", "waltermaleon", "grape")
.mapToInt(e -> e.length())
.forEach(e -> System.out.println(e));
4. flatMap重组操作
// flatMap、flatmapToInt、flatmapToLong、flatmapToDouble
Stream.of("a-b-c-d","e-f-i-g-h")
.flatMap(e->Stream.of(e.split("-")))
.forEach(e->System.out.println(e));
5. limit限制输出操作
// 限制输出前3个
students.stream()
.limit(3)
.collect(Collectors.toList())
.forEach(System.out::println);
6. filter过滤选择操作
// 过滤筛选数据-选择年龄大于25且身高大于160的
List<Student> studentsFilters = students.stream()
.filter(s->s.getAge()>25 && s.getHeight()>160)
.collect(Collectors.toList());
studentsFilters.forEach(System.out::println);
7. 排重及map操作
// distinct
// 提取数据
List<Integer> ages = students.stream()
.map(Student::getAge)
.distinct()
.sorted()
.collect(Collectors.toList());
ages.forEach(System.out::println);
8. peek执行操作
students.stream()
.peek(s->s.setAge(s.getAge()+5))
.collect(Collectors.toList())
.forEach(System.out::println);
System.out.println();
9. skip跳过操作
students.stream()
.skip(3)
.collect(Collectors.toList())
.forEach(System.out::println);
10. collect收集操作
students.stream()
.collect(Collectors.toSet())
.forEach(System.out::println);
11. 收敛规约类计算操作
// count 计算集合中元素数量
long count = Stream.of("apple", "banana", "orange", "waltermaleon", "grape")
.count();
// findFirst 获取流中的第一个元素
Optional<String> stringOptional = Stream.of("apple", "banana", "orange", "waltermaleon", "grape")
.findFirst();
stringOptional.ifPresent(e->System.out.println(e));
// findAny 获取流中的任意一个元素
Optional<String> stringOptional2 = Stream.of("apple", "banana", "orange", "waltermaleon", "grape")
.parallel()
.findAny(); //在并行流下每次返回的结果可能一样也可能不一样
stringOptional.ifPresent(e->System.out.println(e));
//noneMatch 数据流中得没有一个元素与条件匹配的,allMatch是全匹配,anyMatch是任意匹配
boolean result = Stream.of("aa","bb","cc","aa")
.noneMatch(e->e.equals("aa"));
System.out.println(result);
// min,和max
Optional<Integer> integerOptional = Stream.of(0,9,8,4,5,6,-1)
.max((e1,e2)->e1.compareTo(e2));
integerOptional.ifPresent(e->System.out.println(e));
// reduce 规约操作
int sum = Stream.of(0,9,8,4,5,6,-1)
.reduce(0,(e1,e2)->e1+e2);
System.out.println(sum);
12. forEachOrdered有序迭代
//forEachOrdered 适用用于并行流的情况下进行迭代,能保证迭代的有序性
Stream.of(0,2,6,5,4,9,8,-1)
.parallel()
.forEachOrdered(e->{
System.out.println(Thread.currentThread().getName()+": "+e);
});
13. 数组与集合相互转化
//toArray 转成数组
Object[] objects=Stream.of(0,2,6,5,4,9,8,-1).toArray();
// 集合转数组
Integer[] agesArray = new Integer[ages.size()];
ages.toArray(agesArray);
// 获取元素在数组中的位置
int index=Arrays.binarySearch(agesArray,19);
System.out.println(index);