企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
转载自:https://blog.csdn.net/weixin_40001125/article/details/105766744 案例代码:https://gitee.com/flymini/codes02/tree/master/java_/com-learn-java01 **** [TOC] # 1. Stream **1. 生成流** 对于集合来说,共有两个方法可以将集合转化为流。 `stream()`:为集合创建串行流。 `parallelStream()`:为集合创建并行流。 ```java List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); List<String> filtered2 = strings.parallelStream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); ``` **2. `forEach`迭代流中的每个数据**。以下代码片段使用 forEach 输出了10个随机数。 ```java Random random = new Random(); random.ints().limit(10).forEach(System.out::println); ``` **3. `map`用于映射每个元素到对应的结果**。以下代码片段使用 map 输出了元素对应的平方数。 ```java List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); // 获取对应的平方数 List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList()); ``` **4. `filter`方法用于通过设置的条件过滤出元素**。以下代码片段使用 filter 方法过滤出空字符串。 ```java List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 int count = strings.stream().filter(string -> string.isEmpty()).count(); ``` >[warning]&nbsp;1. 如果集合存储的是引用对象,只要调用了`filter`,然后对过滤后的数据做更新,则原数据也会被修改的。对于基本数据类型的包装类和字符串则不存在这个问题。<br/> &nbsp;2. 如果对过滤后的集合本身做add、remove等操作,则不会影响原集合的。 ```java List<Student> list01 = Arrays.asList(new Student("张三"),new Student("李四"),new Student("王五")); List<Student> list02 = list01.stream().filter(l -> l.getName().equals("张三")).collect(Collectors.toList()); System.out.println("list01: " + list01); System.out.println("list02: " + list02); System.out.println("-----------------------"); //对过滤后的数据做修改 list02.get(0).setName("zhangsan"); System.out.println("list01: " + list01); System.out.println("list02: " + list02); /********** 输出如下,可见修改过滤后的数据,原数据也被修改了 ***************/ list01: [Student{name='张三'}, Student{name='李四'}, Student{name='王五'}] list02: [Student{name='张三'}] ----------------------- list01: [Student{name='zhangsan'}, Student{name='李四'}, Student{name='王五'}] list02: [Student{name='zhangsan'}] ``` **5. `sorted`用于对流进行排序**。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序。 ```java Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println); ``` **6. `limit` 方法用于获取指定数量的流**。 以下代码片段使用 limit 方法打印出 10 条数据。 ```java Random random = new Random(); random.ints().limit(10).forEach(System.out::println); ``` **7. `parallelStream` 是流并行处理程序的代替方法**。以下实例我们使用 parallelStream 来输出空字符串的数量。 ```java List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 long count = strings.parallelStream().filter(string -> string.isEmpty()).count(); ``` <br/> # 2. Collectors Collectors类实现了很多归约操作,例如将流转换成集合和聚合元素。 <br/> **1. 交集** ```java List<T> intersect = list1.stream() .filter(list2::contains) .collect(Collectors.toList()); ``` **2. 差集** ```java //(list1 - list2) List<String> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(Collectors.toList()); //(list2 - list1) List<String> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(Collectors.toList()); ``` **3. 并集** ```java //使用并行流 List<String> listAll = list1.parallelStream().collect(Collectors.toList()); List<String> listAll2 = list2.parallelStream().collect(Collectors.toList()); listAll.addAll(listAll2); ``` **4. 去重并集** ```java List<String> listAllDistinct = listAll.stream() .distinct() .collect(Collectors.toList()); //从List中过滤出一个元素 User match = users.stream() .filter((user) -> user.getId() == 1) .findAny().get(); ``` >[info]如果是自定义的数据类型,调用distinct去重,需要自己重写数据类型的equals与hashCode方法。 **5. `List<T>` 转 `List<U>`** ```java //List<Person> getListPerson() //List<Person> 转 List<User> List<User> userList = getListPerson().stream() .filter(p -> p != null) .map(p -> new User(p.getName(), p.getAge())) .collect(Collectors.toList()); ``` **6. `List<T>` 转 `List<Map<String, Object>>`** ```java //public List<Person> getListPerson() //写法1 List<Map<Integer, Person>> mapList1 = getListPerson().stream() .filter(p -> p != null) .map(p -> { Map<Integer, Person> map = new HashMap<>(1); map.put(p.getId(), p); return map; }) .collect(Collectors.toList()); //写法2 List<Map<Integer, Person>> mapList2 = getListPerson().stream() .filter(p -> p != null) .collect(ArrayList::new, (list, p) -> { Map<Integer, Person> map = new HashMap<>(1); map.put(p.getId(), p); list.add(map); }, List::addAll); ``` **7. Map 转 List** ```java //public Map<Integer, Person> getMapPerson() //写法1 List<Person> personList = getMapPerson().entrySet().stream() .filter(p -> p != null) .sorted(Comparator.comparing(Map.Entry::getKey)) .map(p -> p.getValue()) .collect(Collectors.toList()); ``` **8. List 转 Map** ```java //写法1 //(k1, k2) -> k1 表示存在相同的键,则只保留k1对应的元素 Map<Integer, Person> personMap1 = personList.stream() .filter(p -> p != null) .collect(Collectors.toMap(p -> p.getId(), p -> p, (k1, k2) -> k1)); //写法2 //该写法如果存在重复的key,则会报错 Duplicate key Map<Integer, Person> personMap2 = personList.stream() .filter(p -> p != null) .collect(Collectors.toMap(p -> p.getId(), p -> p)); //写法3 //如果存在相同的键,则保留第2个元素 Map<Integer, Person> personMap3 = personList.stream() .filter(p -> p != null) .collect(HashMap::new, (map, p) -> map.put(p.getId(), p), Map::putAll); ``` **`Map<T>` 转 `Map<U>`** ```java //Map<Integer, Person> getMapPerson() //Map<Integer, Person> 转 Map<Integer, User> Map<Integer, User> userMap = getMapPerson().entrySet().stream() .filter(p -> p != null) .collect(Collectors.toMap( item -> item.getKey(), item -> new User(item.getValue().getName(), item.getValue().getAge()) )); ``` **9. 其他转换为Set** ```java //public Stream<Person> getStreamPerson() //写法1 Set<Person> personSet1 = getStreamPerson().filter(p -> p != null).collect(HashSet::new, HashSet::add, HashSet::addAll); //写法2 Set<Person> personSet2 = getStreamPerson().filter(p -> p != null).collect(Collectors.toSet()); ``` **10. `Collectors.groupingBy` 分组后操作** ```java //共有3个重载方法 public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream) public static <T, K, D, A, M extends Map<K, D>> Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier, Supplier<M> mapFactory, Collector<? super T, A, D> downstream) ``` (1)分组统计。 ```java Map<String, Long> sexCount = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.counting())); System.out.println(sexCount); //{女=2, 男=3} ``` (2)分组求和。 ```java //写法1 Map<String, Integer> ageSum1 = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.summingInt(Person::getAge))); //写法2 Map<String, Integer> ageSum2 = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.reducing(0, Person::getAge, Integer::sum))); System.out.println(ageSum2); //{女=51, 男=78} ``` (3)分组求最大值、最小值。 ```java //最大值 Map<String, Optional<Person>> ageMax = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.maxBy(Comparator.comparing(Person::getAge)))); //最小值 Map<String, Optional<Person>> ageMin = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.minBy(Comparator.comparing(Person::getAge)))); System.out.println(ageMax); //{女=Optional[Person{id=1004, name='小梅', age=26, sex='女'}] // , 男=Optional[Person{id=1005, name='王五', age=27, sex='男'}]} System.out.println(ageMin); //{女=Optional[Person{id=1003, name='小美', age=25, sex='女'}] // , 男=Optional[Person{id=1001, name='张三', age=25, sex='男'}]} ``` (4)分组求均值。 ```java Map<String, Double> ageAvg = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.averagingInt(Person::getAge))); System.out.println(ageAvg); //{女=25.5, 男=26.0} ``` (5)根据性别分组。 ```java //写法1 Map<String, List<Person>> personListMap1 = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.mapping(p -> p, Collectors.toList()))); //写法2 Map<String, List<Person>> personListMap2 = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex, Collectors.toList())); //写法3 Map<String, List<Person>> personListMap3 = personList.stream() .filter(p -> p != null) .collect(Collectors.groupingBy(Person::getSex)); System.out.println(personListMap3); //{女=[Person{id=1003, name='小美', age=25, sex='女'}, Person{id=1004, name='小梅', age=26, sex='女'}], // 男=[Person{id=1001, name='张三', age=25, sex='男'}, Person{id=1002, name='李四', age=26, sex='男'}, // Person{id=1005, name='王五', age=27, sex='男'}]} ``` **11. `Collectors.partitioningBy` 分组后操作** Collectors.partitioningBy 与 Collectors.groupingBy 不同的是:Collectors.partitioningBy 只能分为两组,`true`为一组,`false`为一组。 ```java //共有2个重载方法 public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) public static <T, D, A> Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream) ``` (1)例。 ```java Map<Boolean, List<Person>> personListMap = personList.stream() .filter(p -> p != null) .collect(Collectors.partitioningBy(p -> "男".equals(p.getSex()))); System.out.println(personListMap); //{false=[Person{id=1003, name='小美', age=25, sex='女'}, Person{id=1004, name='小梅', age=26, sex='女'}], // true=[Person{id=1001, name='张三', age=25, sex='男'}, Person{id=1002, name='李四', age=26, sex='男'}, // Person{id=1005, name='王五', age=27, sex='男'}]} Map<Boolean, Integer> ageSum = personList.stream() .filter(p -> p != null) .collect(Collectors.partitioningBy(p -> "男".equals(p.getSex()), Collectors.summingInt(Person::getAge))); System.out.println(ageSum); //{false=51, true=78} ``` **12. `Collectors.joining`字符串连接** ```java //共有2个重载方法 public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) public static Collector<CharSequence, ?, String> joining(CharSequence delimiter, //分割符 CharSequence prefix, //前缀符号 CharSequence suffix) //后缀符号 ``` (1)例。 ```java String nameString = personList.stream() .filter(p -> !Objects.isNull(p)) .map(Person::getName) .collect(Collectors.joining(",", "[", "]")); System.out.println(nameString); //[张三,李四,小美,小梅,王五] ``` **13. `Collectors.summarizing(Int/Long/Double)`** 一次性求出平均值averaging、总数couting、最小值minBy、最大值maxBy、求和suming。 ```java Map<String, IntSummaryStatistics> sisMap = personList.stream() .filter(p -> !Objects.isNull(p)) .collect(Collectors.groupingBy(Person::getSex, Collectors.summarizingInt(Person::getAge))); System.out.println("男:" + sisMap.get("男").getMax() + ", " + sisMap.get("男").getMin() + ", " + sisMap.get("男").getAverage() + ", " + sisMap.get("男").getCount() + ", " + sisMap.get("男").getSum()); //男:27, 25, 26.0, 3, 78 System.out.println("女:" + sisMap.get("女").getMax() + ", " + sisMap.get("女").getMin() + ", " + sisMap.get("女").getAverage() + ", " + sisMap.get("女").getCount() + ", " + sisMap.get("女").getSum()); //女:26, 25, 25.5, 2, 51 ```