前言:
而今各位老铁们对“c语言stream”大概比较注意,你们都想要了解一些“c语言stream”的相关文章。那么小编同时在网摘上搜集了一些关于“c语言stream””的相关内容,希望我们能喜欢,兄弟们快快来了解一下吧!Stream简介
Stream流是java 8 中新引入的特性,用来处理集合中的数据,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。
Stream不是数据结构,也不保存数据,它是有关算法和计算的,更像一个高级版本的迭代器Iterator。原始版本的 Iterator,只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“判断是否包含某个字符”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。
Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,可以很方便地写出高性能的并发程序。
Stream的使用
流操作的类型有三种:
(1)创建流
(2)修改流元素(中间操作,Intermediate Operations)
(3)消费流元素(终端操作,Terminal Operations)
创建流
流有两种:(1)stream() : 创建串行流。(2)parallelStream() : 创建并行流。
并行流的特点就是将一个大任务切分成多个小任务,无序一起执行,当然如果我们需要顺序输出的话可以使用forEachOrdered,速度会比串行流快一些。它通过默认的ForkJoinPool,可能提高你的多线程任务的速度。
(1) 通过Stream.of()将元素转化成流
Stream.of创建流Stream<String> stream = Stream.of("你", "我", "她");
(2)每个集合都可以通过调用 stream() 方法来产生一个流
//String [] strArray = new String[] {"a", "b", "c"};stream = Stream.of(strArray);stream = Arrays.stream(strArray);// List<String> list = Arrays.asList(strArray);stream = list.stream();//Set<String> w = new HashSet<>(Arrays.asList(strArray))stream = w.stream();
使用举例
案例里使用的类
class Person { private String name; // 姓名 private int salary; // 战斗力 private int age; // 年龄 private String sex; //性别 private String area; // 必杀技 // 构造方法 public Person(String name, int salary, int age,String sex,String area) { this.name = name; this.salary = salary; this.age = age; this.sex = sex; this.area = area; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } 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; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", salary=" + salary + ", age=" + age + ", sex='" + sex + '\'' + ", area='" + area + '\'' + '}'; } }
(1) 遍历/匹配(foreach/find/match)
Stream也是支持类似集合的遍历和匹配元素的,只是Stream中的元素是以Optional类型存在的。Optional类是一个可以为null的容器对象,调用get()方法会返回该对象。
@Test public void streamTest1() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 30, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); // 遍历输出符合条件的对象, 战斗力大于8000 personList.stream().filter(person -> person.getSalary() > 8000).forEach(System.out::println); // 匹配第一个 Optional<Person> findFirst = personList.stream().filter(person -> person.getAge() > 18).findFirst(); System.out.println("匹配第一个值:" + findFirst.get()); // 匹配随机一个(适用于并行流) Optional<Person> findAny = personList.parallelStream().filter(person -> person.getAge() > 18).findAny(); System.out.println("匹配随机一个值:" + findAny.get()); // 是否包含符合特定条件 年龄大于20 boolean anyMatch = personList.stream().anyMatch(person -> person.getAge() > 20); System.out.println("是否存在年龄大于20的:" + anyMatch); }
运行结果:
(2)筛选(filter)
筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。
@Test public void streamTest2() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 30, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); //筛选出所有战斗力大于8000的 List<Person> list = personList.stream().filter(person -> person.getSalary() > 8000).collect(Collectors.toList()); System.out.println("战斗力大于8000的值:" + list); }
运行结果:
(3)聚合(max/min/count/sum)
max、min、count、sum这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。
@Test public void streamTest3() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); //获取年龄最大的 Optional<Person> max = personList.stream().max(Comparator.comparing(Person::getAge)); System.out.println("年龄最大的是:" + max.get()); //获取战斗力最小的 Optional<Person> min = personList.stream().min(Comparator.comparing(Person::getSalary)); System.out.println("战斗力最小的是:" + min.get()); //计算战斗力大于8000的有几个人 long count = personList.stream().filter(person -> person.getSalary() > 8000).count(); System.out.println("战斗力大于8000的人数是:" + count); //计算总年龄是多少 int sum = personList.stream().mapToInt(person -> person.getAge()).sum(); System.out.println("总年龄是是:" + sum); }
运行结果:
(4)排序(sorted)
stream中有两种排序:
sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):自定义排序,自定义Comparator排序器
@Test public void streamTest4() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); //按战斗力升序排序(自然排序) List<Person> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).collect(Collectors.toList()); System.out.println("按战斗力升序排序:" + newList); //按战斗力降序排序(自然排序) List<Person> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).collect(Collectors.toList()); System.out.println("按战斗力降序排序:" + newList2); // 先按年龄再按战斗力排序(自定义排序 降序) List<Person> newList3 = personList.stream().sorted((p1, p2) -> { if (p1.getAge() == p2.getAge()) { return p2.getSalary() - p1.getSalary(); } else { return p2.getAge() - p1.getAge(); } }).collect(Collectors.toList()); System.out.println("先按年龄再按战斗力:" + newList3); }
运行结果:
(5) 映射(map/flatMap)
映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
@Test public void streamTest5() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); //将人物和必杀技组合, List<String> strList = personList.stream().map(person -> person.getName() + "-->" + person.getArea()).collect(Collectors.toList()); System.out.println("人物和必杀技组合:" + strList); }
运行结果:
(6)归约(reduce)
归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
@Test public void streamTest6() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1","须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2","治疗术")); personList.add(new Person("自来也", 8200, 30, "1","通灵术")); personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2","百豪之术")); //求战斗力总和 方式1 Integer sum = personList.stream().map(Person::getSalary).reduce((x,y) -> x + y).get(); System.out.println("战斗力总和(方式1):" + sum); //求战斗力总和 方式2 Integer sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum).get(); System.out.println("战斗力总和(方式2):" + sum2); //求战斗力总和 方式3 Integer sum3 = personList.stream().map(Person::getSalary).reduce(0,Integer::sum); System.out.println("战斗力总和(方式3):" + sum3); //求年龄的乘积 Integer product = personList.stream().map(Person::getAge).reduce((x,y) -> x * y).get(); System.out.println("年龄的乘积:" + product); //求战斗力最大的值 Integer max = personList.stream().map(Person::getSalary).reduce(1,Integer::max); System.out.println("斗力最大的值:" + max); }
运行结果:
(7)收集(collect)
收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。主要依赖java.util.stream.Collectors类内置的静态方法。
(8)归集(toList/toSet/toMap)
因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap是比较常见的用法
@Test public void streamTest7() { List<Person> personList = new ArrayList<Person>(); personList.add(new Person("鸣人", 8900, 18, "1", "螺旋丸")); personList.add(new Person("佐助", 8800, 18, "1", "须佐能乎")); personList.add(new Person("小樱", 7800, 17, "2", "治疗术")); personList.add(new Person("自来也", 8200, 30, "1", "通灵术")); personList.add(new Person("大蛇丸", 9500, 31, "1", "八岐大蛇")); personList.add(new Person("纲手", 7900, 29, "2", "百豪之术")); //必杀技list集合 List<String> list = personList.stream().map(person -> person.getArea()).collect(Collectors.toList()); System.out.println("必杀技集合toList:" + list); //大于18的年龄set集合 Set<Integer> set = personList.stream().filter(person -> person.getAge() > 18).map(Person::getAge).collect(Collectors.toSet()); System.out.println("大于18的年龄集合toSet:" + set); //战斗力大于8000的map集合 (写法1) Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000) .collect(Collectors.toMap(Person::getName, p -> p)); System.out.println("战斗力大于8000的集合toMap:" + map); //战斗力大于8000的map集合 (写法2) Map<?, Person> map2 = personList.stream().filter(p -> p.getSalary() > 8000) .collect(Collectors.toMap(Person::getName, Function.identity())); System.out.println("战斗力大于8000的集合toMap:" + map2); }
运行结果:
总结
好了,以上就是我总结的Stream的常见用法,感谢大家的阅读,如果有什么疑问或者建议,欢迎评论区留下你的独到见解~
标签: #c语言stream