java8新特性Stream流操作详解及实战3
Posted 孔子-说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8新特性Stream流操作详解及实战3相关的知识,希望对你有一定的参考价值。
java8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的 Lambda,给我们操作集合(Collection)提供了极大的便利。本文主要介绍Stream的排序、去重、合并操作,以及常用方法简单汇总。
5、Stream常用操作示例实战
Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。Stream中的元素是以Optional类型存在的。
创建一个案例使用的员工类Person:
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;
// 省略了get和set,请自行添加
5.7 排序(sorted)
sorted,中间操作。有两种排序:
- sorted():自然排序,流中元素需实现Comparable接口
- sorted(Comparator com):Comparator排序器自定义排序
sorted源码
Stream<T> sorted();
@Override
public final Stream<P_OUT> sorted()
return SortedOps.makeRef(this);
sorted(Comparator com)源码
Stream<T> sorted(Comparator<? super T> comparator);
@Override
public final Stream<P_OUT> sorted(Comparator<? super P_OUT> comparator)
return SortedOps.makeRef(this, comparator);
示例:
将员工按工资由高到低(工资一样则按年龄由大到小)排序
public class StreamTest
public static void main(String[] args)
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Sherry", 9000, 24, "female", "New York"));
personList.add(new Person("Tom", 8900, 22, "male", "Washington"));
personList.add(new Person("Jack", 9000, 25, "male", "Washington"));
personList.add(new Person("Lily", 8800, 26, "male", "New York"));
personList.add(new Person("Alisa", 9000, 26, "female", "New York"));
// 按工资升序排序(自然排序)
List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
.collect(Collectors.toList());
// 按工资倒序排序
List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName).collect(Collectors.toList());
// 先按工资再按年龄升序排序
List<String> newList3 = personList.stream()
.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
.collect(Collectors.toList());
// 先按工资再按年龄自定义排序(降序)
List<String> newList4 = personList.stream().sorted((p1, p2) ->
if (p1.getSalary() == p2.getSalary())
return p2.getAge() - p1.getAge();
else
return p2.getSalary() - p1.getSalary();
).map(Person::getName).collect(Collectors.toList());
System.out.println("按工资升序排序:" + newList);
System.out.println("按工资降序排序:" + newList2);
System.out.println("先按工资再按年龄升序排序:" + newList3);
System.out.println("先按工资再按年龄自定义降序排序:" + newList4);
5.8 去重、合并(distinct、skip、limit)
流也可以进行合并、去重、限制、跳过等切片操作。
- limit(n):获取n个元素,限制获取元素的个数
- skip(n):跳过n元素,配合limit(n)可实现分页
- distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
distinct(去重)源码
Stream<T> distinct();
@Override
public final Stream<P_OUT> distinct()
return DistinctOps.makeRef(this);
skip(跳过)源码
Stream<T> skip(long n);
@Override
public final Stream<P_OUT> skip(long n)
if (n < 0)
throw new IllegalArgumentException(Long.toString(n));
if (n == 0)
return this;
else
return SliceOps.makeRef(this, n, -1);
limit源码
Stream<T> limit(long maxSize);
@Override
public final Stream<P_OUT> limit(long maxSize)
if (maxSize < 0)
throw new IllegalArgumentException(Long.toString(maxSize));
return SliceOps.makeRef(this, 0, maxSize);
示例:
public class StreamTest
public static void main(String[] args)
String[] arr1 = "a", "b", "c", "d" ;
String[] arr2 = "d", "e", "f", "g" ;
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
// concat:合并两个流 distinct:去重
List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
// limit:限制从流中获得前n个数据
List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
// skip:跳过前n个数据 这里的1代表把1代入后边的计算表达式
List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
System.out.println("流合并:" + newList);
System.out.println("limit:" + collect);
System.out.println("skip:" + collect2);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wa9Y4zRn-1667957752122)(/upload/2022/07/image-1657590174931.png)]
6、常用方法简单汇总
6.1 计算两个list中的差集
//计算两个list中的差集
List<String> reduce1 = allList.stream().filter(item -> !wList.contains(item)).collect(Collectors.toList());
6.2 stream() 和 parallelStream()
使用Collection下的 stream() 和 parallelStream() 方法(最为常用)
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //顺序流
Stream<String> stringStream = list.parallelStream(); //并行流
6.3 将数组转成流
使用Arrays 中的 stream() 方法,将数组转成流
Integer[] nums = new Integer[]10,2,3,5;
Stream<Integer> Integerstream = Arrays.stream(nums);
6.4 静态方法of()、iterate()、generate()
使用Stream中的静态方法:of()、iterate()、generate()
Stream<Integer> TestStream = Stream.of(1,2,3,4);
//iterate()、generate()方法可以创建无限流,可以通过limit()方法来限制数量。
Stream<Integer> TestStream2 = Stream.iterate(0,x->x+2);
Stream<Integer> TestStream3 = Stream.generate(()-> new Random().nextInt(10));
Stream<Integer> TestStream4 = Stream.iterate(0,x->x+2).limit(10);
6.5 文件内容转为流
使用 BufferedReader.lines() 方法,将每行内容转成流
BufferedReader reader = new BufferedReader(new FileReader("F:\\\\test_stream.txt"));
Stream<String> lineStream = reader.lines();
//上面可以写成一行
Stream<String> lineStream2 = new BufferedReader(new FileReader("F:\\\\test_stream.txt")).lines();
6.6 字符串分隔成流
使用 Pattern.splitAsStream() 方法,将字符串分隔成流
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream2 = pattern.splitAsStream("a,b,c,d");
6.7 筛选与切片
- filter:过滤流中的某些元素
- limit(n):获取n个元素,限制获取元素的个数
- skip(n):跳过n元素,配合limit(n)可实现分页
- distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
Stream<Integer> stream = Stream.of(6,6,6,12,22,12,213,111,7,9,10);
Stream<Integer> streamFilter = stream.filter(item -> item > 10) // 12 22 12 213 111
.distinct() //12 22 213 111
.skip(2) //213 111
.limit(1);//213
streamFilter.forEach(System.out::println);
6.8 匹配、聚合操作
- allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
- noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
- anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
- findFirst:返回流中第一个元素
- findAny:返回流中的任意元素
- count:返回流中元素的总个数
- max:返回流中元素最大值
- min:返回流中元素最小值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
boolean allMatch = list.stream().allMatch(e -> e > 10); //false
boolean noneMatch = list.stream().noneMatch(e -> e > 10); //true
boolean anyMatch = list.stream().anyMatch(e -> e > 4); //true
Integer findFirst = list.stream().findFirst().get(); //1
Integer findAny = list.stream().findAny().get(); //1
long count = list.stream().count(); //5
Integer max = list.stream().max(Integer::compareTo).get(); //5
Integer min = list.stream().min(Integer::compareTo).get(); //1
以上是关于java8新特性Stream流操作详解及实战3的主要内容,如果未能解决你的问题,请参考以下文章