Java的stream流的使用
一、流是什么?
1、从支持数据处理操作的源生成元素序列.数据源可以是集合,数组或IO资源。
从操作角度来看,流与集合是不同的. 流不存储数据值; 流的目的是处理数据,它是关于算法与计算的。
如果把集合作为流的数据源,创建流时不会导致数据流动; 如果流的终止操作需要值时,流会从集合中获取值; 流只使用一次。
流中心思想是延迟计算,流直到需要时才计算值。
2、特性:
不是数据结构,不会保存数据。
不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)
惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。
二、Stream API
三、具体案例实现
//Person实体类
public class Person {
private String name;
private int age;
private int salary;
public Person(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
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 int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
ublic class Main {
public static void main(String[] args) {
// write your code here
List<Integer> list= Arrays.asList(7,6,9,3,8,2,1);
//遍历输出符合条件的元素
list.stream().filter(x->x>6).forEach(System.out::println);
//匹配第一个
Optional<Integer> findFirst=list.stream().filter(x->x>6).findFirst();
//匹配任意(适用于并行流)
Optional<Integer> findAny=list.parallelStream().filter(x->x>6).findAny();
//是否包含符合特定条件的元素
boolean anyMatch=list.stream().anyMatch(x->x<6);
System.out.println("匹配第一个值:"+findFirst.get());
System.out.println("匹配任意一个值:"+findAny.get());
System.out.println("是否存在大于6的值:"+anyMatch);
filter01();
test01();
test02();
test03();
test04();
test05();
test06();
test07();
test08();
//test09();
test10();
test11();
}
static List<Person> personList = new ArrayList<Person>();
private static void initPerson() {
personList.add(new Person("张三", 8, 3000));
personList.add(new Person("李四", 18, 5000));
personList.add(new Person("王五", 28, 7000));
personList.add(new Person("孙六", 38, 9000));
}
/**
* 筛选员工中已满18周岁的人,并形成新的集合
*/
private static void filter01(){
initPerson();
List<Person> collect=personList.stream().filter(x->x.getAge()>=18).collect(Collectors.toList());
// for(Person p:collect){
// System.out.println(p.toString());
// }
System.out.println(collect);
}
/**
* 获取String集合中的最大值
*/
private static void test01(){
List<Integer> list=Arrays.asList(1,17,27,7);
Optional<Integer> max=list.stream().max(Integer::compareTo);
//自定义排序
Optional<Integer> max2=list.stream().max(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println(max2);
}
/**
* 获取员工中年龄最大的人
*/
private static void test02(){
initPerson();
//Comparator接口可用来排序,需要比较两个对象谁排在前谁排在后:用于分组,需要比较两个对象是否是属于同一组
Comparator<? super Person> comparator=Comparator.comparingInt(Person::getAge);
Optional<Person> max=personList.stream().max(comparator);
System.out.println(max);
}
/**
* 英文字符串数组的元素全部改为大写
*/
private static void test03(){
// Array.asList()方法的作用是将数组或一些元素转为集合,不能使用其修改集合相关的方法
List<String> list=Arrays.asList("zhangsan","lisi","wangwu","sunliu");
list.stream().forEach(t->t.toUpperCase());
// ->和::都可以
List<String> collect=list.stream().map(t->t.toUpperCase()).collect(Collectors.toList());
List<String> collect2=list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(collect);
System.out.println(collect2);
}
/**
* 整数数组每个元素+3
*/
private static void test04(){
List<Integer> list=Arrays.asList(1,17,27,7);
List<Integer> collect=list.stream().map(x->x+3).collect(Collectors.toList());
System.out.println(collect);
}
/**
* 公司效益好,每人涨2000
*/
private static void test05(){
initPerson();
List<Person> collect=personList.stream().map(x->{
x.setSalary(x.getSalary()+2000);
return x;
}).collect(Collectors.toList());
System.out.println(collect);
}
/**
* 将两个字符数组合并成一个新的字符数组
*/
private static void test06(){
String[] arr={"z,h,a,n,g","s,a,n"};
List<String> list=Arrays.asList(arr);
System.out.println(list);
List<String> collect=list.stream().flatMap(x->{
// split()将一个字符串分割为子字符串,然后将结果作为字符串数组返回
String[] array=x.split(",");
Stream<String> stream=Arrays.stream(array);
return stream;
}).collect(Collectors.toList());
System.out.println(collect);
}
/**
* 求Integer集合的元素之和、乘积和最大值
*/
public static void test07() {
List<Integer> list=Arrays.asList(1,2,3,4);
//求和
Optional<Integer> reduce=list.stream().reduce((x,y)->x+y);
System.out.println("求和:"+reduce);
//求积
Optional<Integer> reduce2=list.stream().reduce((x,y)->x*y);
System.out.println("求积:"+reduce2);
//求最大值
Optional<Integer> reduce3=list.stream().reduce((x,y)->x>y?x:y);
System.out.println(reduce3);
}
/**
* 求所有员工的工资之和和最高工资
*/
public static void test08(){
initPerson();
Optional<Integer> reduce=personList.stream().map(Person::getSalary).reduce(Integer::sum);
Optional<Integer> reduce2=personList.stream().map(Person::getSalary).reduce(Integer::max);
System.out.println("工资之和:"+reduce);
System.out.println("最高工资:"+reduce2);
}
/**
* 取出大于18岁的员工转为map
*/
private static void test09(){
initPerson();
Map<String,Person> collect=personList.stream().filter(x->x.getAge()>18).collect(Collectors.toMap(Person::getName,y->y));
System.out.println(collect);
}
/**
* 统计员工人数、平均工资、工资总额、最高工资
*/
private static void test10(){
// 统计员工人数
Long count=personList.stream().collect(Collectors.counting());
// 求平均工资
Double average=personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
// 求最高工资
Optional<Integer> max=personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
// 求工资之和
Integer sum=personList.stream().collect(Collectors.summingInt(Person::getSalary));
// 一次性统计所有信息
DoubleSummaryStatistics collect=personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("统计员工人数:"+count);
System.out.println("求平均工资:"+average);
System.out.println("求最高工资:"+max);
System.out.println("求工资之和"+sum);
System.out.println("一次性统计所有信息:"+collect);
}
private static void test11(){
// 按工资升序排序(自然排序)
List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
.collect(Collectors.toList());
// 按工资倒序排序
List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName).collect(Collectors.toList());
// 先按工资再按年龄升序排序
List<String> newList3 = personList.stream()
.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
.collect(Collectors.toList());
// 先按工资再按年龄自定义排序(降序)
List<String> newList4 = personList.stream().sorted((p1, p2) -> {
if (p1.getSalary() == p2.getSalary()) {
return p2.getAge() - p1.getAge();
} else {
return p2.getSalary() - p1.getSalary();
}
}).map(Person::getName).collect(Collectors.toList());
System.out.println("按工资升序排序:" + newList);
System.out.println("按工资降序排序:" + newList2);
System.out.println("先按工资再按年龄升序排序:" + newList3);
System.out.println("先按工资再按年龄自定义降序排序:" + newList4);
}
}