java——》Stream 梦里梦外; 2024-02-19 19:14 55阅读 0赞 版权声明:本文为博主原创文章,无需授权即可转载,甚至无需保留以上版权声明,转载时请务必注明作者。 [https://blog.csdn.net/weixin\_43453386/article/details/88643166][https_blog.csdn.net_weixin_43453386_article_details_88643166] #### java——》Stream #### * 一、流的生成方式 * * 1、由值创建流 * 2、由数组创建流 * 3、从文件生成流 * 4、由函数生成流 * 二、流操作 * 三、详细使用 * * * 1、stream():创建串行流 * 2、parallelStream():创建并行流 * 3、forEach():迭代流中的每个数据 * 4、map():映射每个元素到对应的结果 * 5、filter():条件过滤 * 6、limit():指定数量的流 * 7、sorted():对流进行排序 * 8、collect(): 操作流的结果 * * 1)结果:lList——》Collectors.toList() * 2)结果:String——》Collectors.joining(", ") * 9、max()、min()、sum()、average() * 四、实例代码 ## 一、流的生成方式 ## ### 1、由值创建流 ### //字符串流 Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); //空流 Stream<String> emptyStream = Stream.empty(); ### 2、由数组创建流 ### int[] numbers = { 2, 3, 5, 7, 11, 13}; IntStream sum = Arrays.stream(numbers); ### 3、从文件生成流 ### > java.nio.file.Files的静态方法lines返回一个由文件每一行组成一个元素的字符串流 Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset()); ### 4、由函数生成流 ### > iterate方法的第一个参数是初始值,第二个参数为一元操作函数接口UnaryOperator< T >,上面的代码会无穷尽地生成以0开始,以2为步长递增的整数,如果不使用limit的话。 > > > generate接受一个参数供应者Supplier< T >以为流提供新的元素,上面的代码若没有limit(5)的限制将会生成无限流 Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println); Stream.generate(Math::random).limit(5).forEach(System.out::println); Stream.generate(() -> Math.random()).limit(5).forEach(System.out::println); ## 二、流操作 ## <table> <tbody> <tr> <td>生成流</td> <td>串行流</td> <td>stream()</td> </tr> <tr> <td>串行流</td> <td>parallelStream()</td> </tr> <tr> <td>中间操作</td> <td>过滤</td> <td>filter()</td> </tr> <tr> <td>去重</td> <td>distinct()</td> </tr> <tr> <td>排序</td> <td>sorted()</td> </tr> <tr> <td>每个元素的结果</td> <td>map()</td> </tr> <tr> <td>抽取</td> <td>flatMap()</td> </tr> <tr> <td>个数</td> <td>limit()</td> </tr> <tr> <td>终止操作</td> <td>数据</td> <td>forEach()</td> </tr> <tr> <td>迭代/遍历数据</td> <td>allMatch()</td> </tr> <tr> <td>数据</td> <td>anyMatch()</td> </tr> <tr> <td>数据</td> <td>findAny()</td> </tr> <tr> <td>数据</td> <td>findFirst()</td> </tr> <tr> <td>数值计算</td> <td>sum()</td> </tr> <tr> <td>数据计算</td> <td>max()</td> </tr> <tr> <td>数据计算</td> <td>min()</td> </tr> <tr> <td>数据计算</td> <td>average()</td> </tr> <tr> <td>数据计算</td> <td>min()</td> </tr> <tr> <td>集合</td> <td>reduce()</td> </tr> <tr> <td>集合</td> <td>collect()</td> </tr> </tbody> </table> ## 三、详细使用 ## #### 1、stream():创建串行流 #### List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); #### 2、parallelStream():创建并行流 #### List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 int count = strings.parallelStream().filter(string -> string.isEmpty()).count(); #### 3、forEach():迭代流中的每个数据 #### Random random = new Random(); random.ints().limit(10).forEach(System.out::println); #### 4、map():映射每个元素到对应的结果 #### List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); // 获取对应的平方数 List<Integer> squaresList = numbers.stream().map( i -> i*i).collect(Collectors.toList()); #### 5、filter():条件过滤 #### List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 int count = strings.stream().filter(string -> string.isEmpty()).count(); #### 6、limit():指定数量的流 #### Random random = new Random(); random.ints().limit(10).forEach(System.out::println); #### 7、sorted():对流进行排序 #### Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println); #### 8、collect(): 操作流的结果 #### ##### 1)结果:lList——》Collectors.toList() ##### List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); System.out.println("筛选列表: " + filtered); ##### 2)结果:String——》Collectors.joining(", ") ##### List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("合并字符串: " + mergedString); #### 9、max()、min()、sum()、average() #### List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("列表中最大的数 : " + stats.getMax()); System.out.println("列表中最小的数 : " + stats.getMin()); System.out.println("所有数之和 : " + stats.getSum()); System.out.println("平均数 : " + stats.getAverage()); ## 四、实例代码 ## import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang.StringUtils; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; public class StreamTest { public static void main(String[] args) { List<User> userList = Arrays.asList( new User(1, "张三", 12,"男"), new User(2, "李四", 21, "男"), new User(3,"王五", 32, "男"), new User(4, "赵六", 32, "女")); List<String> strList = Arrays.asList("a1","b1","a2"); List<JSONObject> jsonObjectList = Arrays.asList( JSONObject.parseObject("{'a':'1','b':'1'}"), JSONObject.parseObject("{'a':'2','b':'1'}"), JSONObject.parseObject("{'a':'3','b':'1'}"), JSONObject.parseObject("{'a':'4','b':'1'}")); /*******************************************************************************************************************************************/ /** * 参数:List<String> * 结果:String * 要求:用逗号拼接 */ //方式一 String join1 = String.join(",", strList); System.out.println(join1); //方式二 String join2 = strList.stream() .collect(Collectors.joining(",")); System.out.println(join2); /*******************************************************************************************************************************************/ /** * 参数:List<JSONObject> * 结果:String * 要求:用逗号拼接 */ String join3 = jsonObjectList.stream().map((JSONObject e) ->e.getString("a")).collect(Collectors.joining(",")); System.out.println(join3); /*******************************************************************************************************************************************/ /** * 参数:List<JSONObject> * 结果:List<String> * 要求:用逗号拼接 */ List<String> join4 = jsonObjectList.stream().map((JSONObject e) ->e.getString("a")).collect(toList()); System.out.println(join4); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:List<String> * 要求:把所有的User的name,放入List<String> */ List<String> userNameListStr = userList.stream().map(User::getName).collect(toList()); System.out.println(userNameListStr); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:List<User> * 要求:过滤出符合条件的 * * * Stream<E> stream() ——》返回:Stream接口 * Stream<T> filter(Predicate<? super T> ——》参数:predicate接口类型的变量 * ——》返回:Stream接口 * ——》说明:将所有流对象中的元素进行过滤 * ——》补充:中间操作,在返回结果的基础上再进行其他的流操作 * * void forEach(Consumer<? super T> action) ——》参数:Consumer函数式接口 * ——》返回:无 * ——》说明:执行对每一个元素的操作 * ——》补充:中止操作,不能再调用其他的流操作 */ Map<String, List<User>> str1 = userList.stream().filter(a -> a.getName().equals("张三")).collect(Collectors.groupingBy(User::getName)); System.out.println(str1); userList.stream().filter(a -> a.getName().startsWith("张三")).forEach(System.out::println); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:List<String> * 要求:把所有的User的name,去重,放入List<String> */ List<String> userNameListStr1 = userList.stream().map(User::getName).distinct().collect(toList()); System.out.println(userNameListStr1); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,User> * 要求:key为name,value为User * 注意:name可能重复,如果重复,就会报错:java.lang.IllegalStateException: Duplicate key * */ Map<String,User> map1 = userList.stream().collect(Collectors.toMap(User::getName, Function.identity())); Map<String,User> map_1 = userList.stream().collect(Collectors.toMap(User::getName, user->user)); System.out.println(map1); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,String> * 要求:按User的name分组,key为name,value为sex * */ Map<String,String> map2 = userList.stream().collect(Collectors.toMap(User::getName, User::getSex)); System.out.println(map2); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,String> * 要求:按User的name分组,key为(name+id),value为sex * */ Map<String,String> map3 = userList.stream().collect(Collectors.toMap(e->{ return e.getName().concat("-").concat(""+ e.getId()); }, User::getSex)); System.out.println(map3); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,String> * 要求:key为(name+id),value为sex(sex字段的值可以做额外处理) * */ Map<String,String> map4 = userList.stream().peek(e->{ if(e.getSex() == null){ e.setSex("男"); } }).collect(Collectors.toMap(e->{ return e.getName().concat("-").concat(""+ e.getId()); }, User::getSex)); System.out.println(map4); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,User> * 要求:key为name,value为user * 注意:key存在重复,值以第2个为准 * */ Map<String,User> map5 = userList.stream().collect(Collectors.toMap(User::getName,Function.identity(),(t1, t2) -> t2)); System.out.println(map5); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:List<User> * 要求:按User的name倒序 * */ List<User> userList1 = userList.stream().sorted((a, b) -> { String ad = a.getName(); String bd = b.getName(); if (StringUtils.isBlank(ad)) { ad = ""; } if (StringUtils.isBlank(bd)) { bd = ""; } return bd.compareTo(ad); }).collect(toList()); System.out.println(userList1); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:List<User> * 要求:统一修改User的age * */ List<User> userList2 = new ArrayList<>(); userList2.addAll(userList); userList2.stream().forEach(user -> user.setAge(user.getAge()+100)); userList2.forEach(e->e.getAge()); System.out.println(userList2); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,Map<String,String>> * 要求:按User的name分组,key为sex,value为name * */ Map<String, Map<String, String>> map6 = userList.stream().collect(Collectors.groupingBy(User::getName,Collectors.toMap(User::getSex, User::getName))); System.out.println(map6); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,Map<String,String>> * 要求:按User的name分组,key为sex,value为name(value可以额外处理) * */ Map<String, Map<String, String>> map7 = userList.stream().collect(Collectors.groupingBy(User::getName,Collectors.toMap(User::getSex, e->{ if(e.getAge()==12){ return e.getAge()+100+""; }else{ return e.getAge()+""; } }))); System.out.println(map7); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,Map<String,String>> * 要求:按User的name分组,key为sex(key重复,以第1个为准),value为name(value可以额外处理) * */ Map<String, Map<String, String>> map8 = userList.stream().collect(Collectors.groupingBy(User::getName,Collectors.toMap(User::getSex, e->{ if(e.getAge()==12){ return e.getAge()+100+""; }else{ return e.getAge()+""; } },(e1,e2)->e1))); System.out.println(map8); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,List<User>> * */ Map<String, List<User>> map9 = userList.stream().collect(Collectors.groupingBy(User::getName)); System.out.println(map9); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Map<String,Set<User>> * */ // 方法一: // Map<String, List<User>> map10 = userList.stream().collect(Collectors.groupingBy(User::getId, Collectors.collectingAndThen( // toList(),e -> e.stream().flatMap(c -> c.getNewsIds().stream()).distinct().collect(Collectors.toSet())))); // System.out.println(map10); // 方法二: //1.先分组 Map<String, List<User>> map = userList.stream().collect(Collectors.groupingBy(User::getName)); //2.循环每个分组下的List,把List下的数据去重,放入set Map<String,Set> result = new HashMap<>(); for (Map.Entry<String, List<User>> entry : map.entrySet()) { Set<String> s = new HashSet<>(); List<User> uc = entry.getValue(); for(int i = 0;i<uc.size();i++){ //把字段值放入set中 // s.addAll(uc.get(i).getNewsIds()); } result.put(entry.getKey(),s); } /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Integer * 要求:求和 * */ Integer integer1 = userList.stream().map(User::getAge).reduce(0,Integer::sum); System.out.println(integer1); Integer integer2 = userList.stream().mapToInt(User::getAge).sum(); System.out.println(integer2); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Integer * 要求:排序 * 注意:sorted只是创建排序视图,不影响原来集合顺序 * * Stream<T> sorted() ——》返回:Stream接口 * Stream<T> sorted(Comparator<? super T> ——》参数:Comparator * ——》返回:Stream接口 * ——》说明:一个中间操作,流对象中的元素会默认按照自然顺序进行排序,除非你自己指定一个Comparator接口来改变排序规则 */ List<User> userList3 = userList.stream().sorted().collect(toList()); System.out.println(userList3); /*******************************************************************************************************************************************/ /** * 参数:List<User> * 结果:Integer * 要求:将集合元素转为大写(每个元素映射到大写)->降序排序->迭代输出,不影响原始集合元素 * * Stream<T> sorted() ——》返回:Stream接口 * Stream<T> sorted(Comparator<? super T> ——》参数:Comparator * ——》返回:Stream接口 * ——》说明:一个中间操作,流对象中的元素会默认按照自然顺序进行排序,除非你自己指定一个Comparator接口来改变排序规则 */ List<String> str2 = strList.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a)).collect(Collectors.toList()); System.out.println(str2); /*******************************************************************************************************************************************/ /** * 参数:List<String> * 结果:Boolean * 要求:集合中是否有任一元素匹配以'a'开头 * */ // 集合中是否有任一元素匹配以'a'开头 boolean b1 = strList.stream().anyMatch((s) -> s.startsWith("a")); System.out.println(b1); /*******************************************************************************************************************************************/ /** * 参数:List<String> * 结果:Boolean * 要求:集合中是否所有元素匹配以'a'开头 * */ // 集合中是否所有元素匹配以'a'开头 boolean b2 = strList.stream().allMatch((s) -> s.startsWith("a")); System.out.println(b2); /*******************************************************************************************************************************************/ /** * 参数:List<String> * 结果:Boolean * 要求:集合中是否没有元素匹配以'd'开头 * */ // 集合中是否没有元素匹配以'd'开头 boolean b3 = strList.stream().noneMatch((s) -> s.startsWith("a")); System.out.println(b3); /*******************************************************************************************************************************************/ } } class User{ public int id; public String name; public int age; public String sex; public User(int id, String name, int age,String sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } [https_blog.csdn.net_weixin_43453386_article_details_88643166]: https://blog.csdn.net/weixin_43453386/article/details/88643166
相关 javastream流--基本操作与介绍(持续更新中,用到了我就更新!) javastream在正常开发中使用到的地方还是蛮多了,在这里记一下基本方法的使用: //学生类 private Integer id; 旧城等待,/ 2023年02月09日 10:27/ 0 赞/ 22 阅读
还没有评论,来说两句吧...