网站建设栏目结构表,新闻资讯网站模板,简单的个人网页模板,网络营销的12种手段Java8 API新增了一个新的抽象流Stream#xff0c;它可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作#xff0c;就类似于使用 SQL 执行的数据库查询。Stream就是把集合数据看作流#xff0c;流在管道中传输#xff0c;我们可在管道中进行…Java8 API新增了一个新的抽象流Stream它可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作就类似于使用 SQL 执行的数据库查询。Stream就是把集合数据看作流流在管道中传输我们可在管道中进行排序聚合等操作。
在平时写代码的过程中涉及到集合操作时候Stream API可以极大的提高我们的生产力让我们写出高效率、干净、简洁的代码。Stream API有很多操作可供使用这里主要介绍常用的几个方法。
基础Stream API
forEach
forEach是迭代流中的每一个元素。
Test
public void testForeach() {Random random new Random();ListInteger list new ArrayList();//random.ints(-100,100).limit(10).forEach(System.out::println);random.ints(-100,100).limit(10).forEach(t-list.add(t));System.out.println(list);
}上述是用forEach迭代输出每一个-100至100的随机值输出10个还可以迭代进入一个新的List集合。
map
map对流中每个元素进行操作返回一个新的流
Test
public void testMap(){// 只是对流操作并不会改变原List中的数据//StreamString fruitStream.of(apple,orange,banner,pear);ListString fruit Arrays.asList(apple,orange,banner,pear);fruit.stream().sorted().map(String::toUpperCase).forEach(System.out::println);System.out.println(fruit);// 返回新的流ListString newfruit fruit.stream().map(v-v.toUpperCase()).collect(Collectors.toList());System.out.println(newfruit);
}上述是对每个元素进行大写字母化或输出或返回到新的集合中
filter
filter 方法用于通过设置的条件过滤出元素
/*** Long 数组选取不为Null和大于0的值* param t* return*/
public static Long[] removeNullAndZero(Long[] t) {ListLong list Arrays.asList(t);return list.stream().filter(v-v!null v0).toArray(Long[] :: new);
}/*** 选取String数组 不为Null的值* param t* return*/
public static String[] removeNullAndZero(String[] t) {ListString list Arrays.asList(t);return list.stream().filter(v-v!null).toArray(String[] :: new);
}过滤Null或者大于0的元素
Test
public void testFilter() {ListInteger intList Arrays.asList(8,2,4,1,8,3,10,6,6,15);ListInteger newIntListintList.stream().filter(i-i5).sorted().distinct().collect(Collectors.toList());System.out.println(newIntList);
}上述是过滤大于5的值并且排序取唯一的数字输出到新的集合。
parallelStream
parallelStream 是流并行处理程序的代替方法相比较Stream是多管道操作。它就是基于ForkJoinPool执行并发任务的。
特点
使用parallelStream可以简洁高效的写出并发代码。parallelStream并行执行是无序的。parallelStream提供了更简单的并发执行的实现但并不意味着更高的性能它是使用要根据具体的应用场景。如果cpu资源紧张parallelStream不会带来性能提升如果存在频繁的线程切换反而会降低性能。任务之间最好是状态无关的因为parallelStream默认是非线程安全的可能带来结果的不确定性。
Github上对Parallel做了增强有兴趣可以点击访问。
Test
public void testParallel() {Random random new Random();ListInteger list new ArrayList();random.ints(-10000,10000).limit(10000).forEach(t-list.add(t));long start System.currentTimeMillis();list.stream().filter(e - e 1000 e 2000).collect(Collectors.toList());System.out.println(stream : (System.currentTimeMillis() - start) ms);start System.currentTimeMillis();list.parallelStream().filter(e - e 1000 e 2000).collect(Collectors.toList());System.out.println(parallelStream : (System.currentTimeMillis() - start) ms);
}测试并发处理速度上述代码对此做了测试测试结果parallelStream速度是稍快一点。
Count
Stream API还提供简单的统计操作。
Test
public void testCount() {ListInteger numList Arrays.asList(6, 2, 4, 3, 7, 3, 5, 9);DoubleSummaryStatistics stats numList.stream().mapToDouble((x) - x).summaryStatistics();System.out.println(总个数 : stats.getCount());System.out.println(列表中最大的数 : stats.getMax());System.out.println(列表中最小的数 : stats.getMin());System.out.println(所有数之和 : stats.getSum());System.out.println(平均数 : stats.getAverage());
}简单的统计的功能。
实际应用
我在实际项目对会有集合进行操作使用Stream API能够帮我简洁的解决问题。下面是我实际使用场景。
对象类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;Data
NoArgsConstructor
AllArgsConstructor
public class Person {private String name;private Integer gender;private int age;private double height;
}使用场景
构造数据
static ListPerson createPeople(){ListPerson peoplenew ArrayListPerson();Person personnew Person(张三,0,30,2.8);people.add(person);personnew Person(李四,0,32,1.6);people.add(person);personnew Person(王五,1,32,2.0);people.add(person);personnew Person(王五,1,33,1.6);people.add(person);return people;
}连接某一属性
需要并行显示用,连接某一属性
Test
public void CollectionStreamJoin(){ListPerson peoplecreatePeople();StreamPerson streampeople.stream();// 取出对象的name值并用,连接String names stream.map(v-v.getName()).collect(Collectors.joining(,));System.out.println(names);
}获取某属性唯一值
根据某一个属性值删选对象。只保留唯一的属性值
Test
public void distinctList() {ListPerson peoplecreatePeople();ListPerson distinctlist people.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() - new TreeSet(Comparator.comparing(Person::getName))),ArrayList::new));System.out.println(distinctlist);
}多属性排序
需要用多个属性去进行排序
Test
public void sortField() {ListPerson peoplecreatePeople();people.sort(Comparator.comparing(Person::getAge).reversed().thenComparing(Person::getHeight));System.out.println(JSON.toJSONString(people));
}分组后排序
对象列表先按照一个字段分组并根据另一个字段的大小来排序取第一个对象
Test
public void getOnlyOneByField() {ListPerson peoplecreatePeople();MapString,Person map new HashMap();map people.parallelStream().collect(Collectors.groupingBy(Person::getName,Collectors.collectingAndThen(Collectors.reducing((c1, c2) - c1.getAge()c2.getAge()?c1:c2),Optional::get)));System.out.println(map);
}累加求和
根据某个属性值累加
Test
public void accumulation(){ListPerson peoplecreatePeople();int sumAge people.stream().mapToInt(Person::getAge).sum();System.out.println(sumAge);
}分组求和
根据某个属性分组然后另外一个值求和
/*** 分组求和*/
Test
public void groupSum(){ListPerson peoplecreatePeople();MapInteger, DoubleSummaryStatistics summaryStatisticsMap people.stream().collect(Collectors.groupingBy(Person::getGender,Collectors.summarizingDouble(Person::getHeight)));System.out.println(JSON.toJSONString(summaryStatisticsMap));
}总结
使用Stream API可以让集合操作的代码更为简洁提高生产力。而且本人在写Stream操作的时候思想就跟写SQL语句类似包括分组、聚合、过滤等操作遇到难的可以在思维上借鉴下。