Java --> 不可变集合+Stream流

 

 

 1 import java.util.List;
 2 import java.util.Map;
 3 import java.util.Set;
 4 
 5 public class UnchangeCollectionDemo {
 6     //对不可变集合进行增删修改操作时均会抛出异常:UnsupportedOperationException
 7     public static void main(String[] args) {
 8         //创建List不可变集合
 9         List<Double> lists = List.of(436.5,710.2,358.1,524.8);
10         //lists.add(12.2);
11         //lists.set(0,152.4);
12         System.out.println(lists);
13 
14         //创建Set不可变集合
15         Set<String> sets = Set.of("Java","C#","HTML");
16         //sets.add("MySQL");
17         System.out.println(sets);
18 
19         //创建Map不可变集合
20         Map<String,Integer> maps = Map.of("手表",120,"体恤衫",65,"手机",1850);
21         System.out.println(maps);
22     }
23 }
  • 感受Stream流的优点
 1 java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 
 5 public class StreamTest {
 6     public static void main(String[] args) {
 7         List<String> lists = new ArrayList<>();
 8         Collections.addAll(lists,"小兵","小强","文天祥","小龙","大兵","干将莫邪","小不点");
 9         System.out.println(lists);
10 
11         //1、把集合中姓小的放到新集合中
12         List<String> xiaoLists = new ArrayList<>();
13         for (String s : lists) {
14             if (s.startsWith("")){
15                 xiaoLists.add(s);
16             }
17         }
18         System.out.println(xiaoLists);
19 
20         //2、把集合中姓名长度为3的放到新集合中
21         List<String> namesThreeLength = new ArrayList<>();
22         for (String s : lists) {
23             if (s.length() == 3){
24                 namesThreeLength.add(s);
25             }
26         }
27         System.out.println(namesThreeLength);
28 
29         //3、使用Stream实现,支持链式编程
30         lists.stream().filter(s -> s.startsWith("")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
31     }

示例运行结果:

 

  •  集合、数组获取流的方式:
 1 import java.util.*;
 2 import java.util.stream.Stream;
 3 
 4 public class StreamDemo2 {
 5     public static void main(String[] args) {
 6         //Collection集合获取流
 7         Collection<String> list = new ArrayList<>();
 8         Stream<String> stream = list.stream();
 9 
10         //Map集合获取流
11         Map<String,Integer> maps = new HashMap<>();
12         //键流
13         Stream<String> keyStream = maps.keySet().stream();
14 
15         //值流
16         Stream<Integer> valuesStream = maps.values().stream();
17 
18         //键值对流 map 可-> set
19         Stream<Map.Entry<String, Integer>> keyAndValueStream = maps.entrySet().stream();
20 
21         //数组获取流
22         String[] names = {"太乙真人","孙悟空","哪吒","雷震子"};
23         Stream<String> namesStream = Arrays.stream(names);
24         Stream<String> nameStream2 = Stream.of(names);
25     }
26 }

Student类

 1 public class Student {
 2     private String name;
 3 
 4     public Student() {
 5     }
 6 
 7     public Student(String name) {
 8         this.name = name;
 9     }
10 
11     public String getName() {
12         return name;
13     }
14 
15     public void setName(String name) {
16         this.name = name;
17     }
18 
19     @Override
20     public String toString() {
21         return "Student{" +
22                 "name='" + name + '\'' +
23                 '}';
24     }
25 }

测试类

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 import java.util.stream.Stream;
 5 
 6 public class StreamDemo3 {
 7     public static void main(String[] args) {
 8         List<String> list = new ArrayList<>();
 9         Collections.addAll(list,"后裔","嫦娥","玉兔","张三丰","张昭","张明旺","嫦娥","玉兔","张三丰");
10 //        list.stream().filter(new Predicate<String>() {
11 //            @Override
12 //            public boolean test(String s) {
13 //                return s.startsWith("张");
14 //            }
15 //        });
16 
17         System.out.println("-------Lambda表达式简化--------");
18         list.stream().filter(s -> s.startsWith("")).forEach(s -> System.out.println(s));
19 
20         System.out.println("--------长度为3的---------");
21         long size = list.stream().filter(s -> s.length() == 3).count();
22         System.out.println(size);
23 
24         System.out.println("----------姓张的,只要前两个------------");
25         //list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(s -> System.out.println(s));
26         list.stream().filter(s -> s.startsWith("")).limit(2).forEach(System.out::println); //条件:两个s一样
27 
28         System.out.println("----------跳过前两个姓张的人-----------");
29         list.stream().filter(s -> s.startsWith("")).skip(2).forEach(System.out::println);
30 
31         System.out.println("----Map加工方法,给每个集合前都加上一个”软件学院“-----");
32         //                           原数据类型,加工后数据类型
33 //        list.stream().map(new Function<String, Object>() {
34 //            @Override
35 //            public String apply(String s) {
36 //                return "软件学院" + s;
37 //            }
38 //        });
39         list.stream().map(  s ->  "软件学院" + s).forEach(s -> System.out.println(s));
40 
41         System.out.println("--------需求:把所有的名称 都加工成一个学生对象---------");
42 //        list.stream().map(new Function<String, Student>() {
43 //            @Override
44 //            public Student apply(String s) {
45 //                return new Student(s);
46 //            }
47 //        }).forEach(student -> System.out.println(student.getName()));
48 
49         //list.stream().map(s -> new Student(s)).forEach(student -> System.out.println(student));
50         list.stream().map(Student::new).forEach(System.out::println); //构造器引用,方法引用
51 
52         System.out.println("----合并流------");
53         Stream<String> stream1 = list.stream().filter(s -> s.startsWith(""));
54         Stream<String> stream2 = Stream.of("Java","MySQL","HTML");
55         //public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
56         System.out.println("----被合并的流(?)必须为合并后的流(T)的子类  [distinct(不同的)->去重复]------");
57         Stream<String> stream3 = Stream.concat(stream1,stream2);
58         stream3.distinct().forEach(s -> System.out.println(s));
59 
60         System.out.println("-------通过Stream流对原list集合进行的操作都是返回新的流,并不会对原来的集合造成影响------");
61         list.forEach(s -> System.out.println(s));
62     }
63 }

示例运行结果:

  •  案例需求:某个公司的开发部门,分为开发一部和二部,现在需要进行年终的数据结算。
  • 分析:
  1. 员工信息至少包含了(名称、性别、工资、奖金、处罚记录);
  2. 开发一部有4个员工、开发二部有5个员工;
  3. 分别筛选出2个部门的最高工资,封装成优秀员工对象Topperformer;
  4. 分别统计出2个部门的平均月收入,要求去掉最高和最低工资;
  5. 统计2个部门整体的平均工资,去掉最低和最高工资的平均值

Topperformer类:

 1 public class Topperformer {
 2     private String name;
 3     private double money; //月薪
 4 
 5     public Topperformer() {
 6     }
 7 
 8     public Topperformer(String name, double money) {
 9         this.name = name;
10         this.money = money;
11     }
12 
13     public String getName() {
14         return name;
15     }
16 
17     public void setName(String name) {
18         this.name = name;
19     }
20 
21     public double getMoney() {
22         return money;
23     }
24 
25     public void setMoney(double money) {
26         this.money = money;
27     }
28 
29     @Override
30     public String toString() {
31         return "Topperformer{" +
32                 "name='" + name + '\'' +
33                 ", money=" + money +
34                 '}';
35     }
36 }

测试类:

 1 import java.math.BigDecimal;
 2 import java.math.RoundingMode;
 3 import java.util.ArrayList;
 4 import java.util.Comparator;
 5 import java.util.List;
 6 import java.util.function.Consumer;
 7 import java.util.function.Function;
 8 import java.util.function.Predicate;
 9 import java.util.stream.Stream;
10 
11 public class StreamDemo4 {
12     public static double allMoney_dep1;
13     public static double allMoney_dep2;
14     public static double allMoney_dep1_dep2;
15     public static long all_members;
16 
17     public static void main(String[] args) {
18         List<Employee> department1 = new ArrayList<>();
19         department1.add(new Employee("猪八戒",'',12000,500,null));
20         department1.add(new Employee("孙悟空",'',15000,800,"顶撞师傅"));
21         department1.add(new Employee("沙和尚",'',11000,300,null));
22         department1.add(new Employee("小白龙",'',13500,500,null));
23 
24         List<Employee> department2 = new ArrayList<>();
25         department2.add(new Employee("青狮魔王",'',18000,500,"被文殊菩萨收服"));
26         department2.add(new Employee("白象魔王",'',17000,8000,"被普贤菩萨收服"));
27         department2.add(new Employee("大鹏魔王",'',16000,300,"被如来收服"));
28         department2.add(new Employee("孔雀公主",'',14500,500,null));
29 
30         System.out.println("--------department1部门的最高工资员工----------");
31 //        Employee employee = department1.stream().max(new Comparator<Employee>() {
32 //            @Override
33 //            public int compare(Employee e1, Employee e2) {
34 //                return Double.compare(e1.getSalary() + e1.getBonus(),e2.getSalary() + e2.getBonus());
35 //            }
36 //        }).get();
37         //简化
38         Employee employee = department1.stream().max((e1, e2) ->
39                 Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e1.getBonus())).get();
40         System.out.println(employee);
41         System.out.println("-----1、加工成Topperformer对象------");
42 //        Topperformer topperformer = department1.stream().max((e1, e2) ->
43 //                Double.compare(e1.getSalary() + e1.getBonus(),
44 //                        e2.getSalary() + e1.getBonus())).map(new Function<Employee, Topperformer>() {
45 //            @Override
46 //            public Topperformer apply(Employee employee) {
47 //                return new Topperformer(employee.getName(),employee.getSalary() + employee.getBonus());
48 //            }
49 //        }).get();
50 //        System.out.println(topperformer);
51 
52         System.out.println("---简化---");                //可被替换为Comparator.comparingDouble(e -> e.getSalary() + e.getBonus())
53         Topperformer topperformer2 = department1.stream().max((e1,e2) -> Double.compare(e1.getSalary()+e1.getBonus(),e2.getSalary()+e2.getBonus())).map(
54                 employee1 -> new Topperformer(employee1.getName(),employee1.getSalary()+employee1.getBonus())
55         ).get();
56         System.out.println(topperformer2);
57 
58         System.out.println("---2、统计部门1的平均工资,去掉最高工资和最低工资---");
59         //思路:排序员工平均工资,用skip跳过第一个,再用limit(总员工数 - 2)则可以得到剩余所有员工的工资,内部求和后除以总人数减2
60         department1.stream().sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(),e2.getSalary() + e2.getBonus()))
61                 .skip(1).limit(department1.size() - 2).forEach(new Consumer<Employee>() {
62                     @Override
63                     public void accept(Employee employee) {
64                         allMoney_dep1 += (employee.getBonus()+employee.getSalary());
65                     }
66                 });
67         System.out.println("department1_avgmoney:" + allMoney_dep1 / (department1.size() - 2) * 1.0);
68 
69         System.out.println("---3、统计部门2的平均工资,去掉最高工资和最低工资---");
70         department2.stream().sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(),e2.getSalary() + e2.getBonus()))
71                 .skip(1).limit(department2.size() - 2).forEach(new Consumer<Employee>() {
72                     @Override
73                     public void accept(Employee employee) {
74                         allMoney_dep2 += (employee.getBonus() + employee.getSalary());
75                     }
76                 });
77         System.out.println("department_avgmoney:" + allMoney_dep2);
78 
79         System.out.println("---4、统计2个开发部门整体的平均工资,去掉最低和最高的平均值---");
80         //思路:合并两个集合流在进行统计
81         Stream<Employee> stream1 = department1.stream();
82         Stream<Employee> stream2 = department2.stream();
83         Stream<Employee> stream_sum = Stream.concat(stream1,stream2);
84 
85         all_members = department1.size() + department2.size();
86         stream_sum.sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(),e2.getSalary() + e2.getBonus()))
87                 .skip(1).limit(all_members - 2).forEach(new Consumer<Employee>() {
88                     @Override
89                     public void accept(Employee employee) {
90                         allMoney_dep1_dep2 += (employee.getSalary() + employee.getBonus());
91                     }
92                 });
93         //BigDecimal
94         BigDecimal bigDecimal1 = BigDecimal.valueOf(allMoney_dep1_dep2);
95         BigDecimal bigDecimal2 = BigDecimal.valueOf(all_members - 2);
96         //保留两位小数,四舍五入
97         System.out.println("allMoney_dep1_dep2:" + bigDecimal1.divide(bigDecimal2,2, RoundingMode.HALF_UP));
98     }
99 }

示例运行结果:

 

  •  Stream流的收集操作:
 1 import java.util.*;
 2 import java.util.stream.Collectors;
 3 import java.util.stream.Stream;
 4 
 5 public class StreamDemo5 {
 6     public static void main(String[] args) {
 7         List<String> list = new ArrayList<>();
 8         Collections.addAll(list,"后裔","嫦娥","玉兔","张三丰","张昭","张明旺","嫦娥","玉兔","张三丰");
 9 
10         //收集姓张的
11         Stream<String> zhangStream = list.stream().filter(s -> s.startsWith(""));
12         List<String> zhangList = zhangStream.collect(Collectors.toList());
13         //List<String> zhangList = zhangStream.toList();  jdk16开始,新集合不能被修改
14         System.out.println("List集合:" + zhangList);
15 
16         //注意:流只能被操作一次
17         Stream<String> zhangStream2 = list.stream().filter(s -> s.startsWith(""));
18         Set<String> zhangSet =  zhangStream2.collect(Collectors.toSet());
19         System.out.println("Set集合:" + zhangSet);
20 
21         //收集成字符数组
22         Stream<String> zhangStream3 = list.stream().filter(s -> s.startsWith(""));
23         //Object[] zhangArrays = zhangStream3.toArray();
24         String[] zhangArrays = zhangStream3.toArray(String[]::new); //一定要转换成String数组(拓展知识)
25 
26         System.out.println("数组:" + Arrays.toString(zhangArrays));
27     }
28 }

示例运行结果:

 

 

posted @ 2022-06-22 11:27  羽梦齐飞  阅读(107)  评论(0编辑  收藏  举报