概述
StreamAPI
位于java.util.stream
包下。
使用StreamAPI对集合数据进行操作,类似于使用SQL执行的数据库查询,并筛选需要的数据。
stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
注意:
- Stream自己不会存储元素
- Stream不会改变原对象,相反,它们会返回一个持有结果的新Stream。
- Stream操作是延迟执行的。
Stream的三个步骤
-
创建stream
一个数据源(集合,数组等),获取一个流
-
中间操作
一个中间操作,对数据源的数据进行处理
-
终止操作(终端操作)
一旦执行终止操作,就执行中间操作链,产生结果,之后,不会再被使用。
Stream创建方式
1. 集合方式
@Test
public void test1(){
List<String> list = Arrays.asList("2311", "jkll", "0988", "oppe", "uuuu");
//default Stream<E> stream();返回顺序流
Stream<String> stream = list.stream();//Collection接口中的stream()
//default Stream<E> parallelStream();返回并行流
Stream<String> parallelStream = list.parallelStream();
}
2. 数组方式
@Test
public void test2(){
int[] arr = new int[]{1,4,2,3,4};
//static <T> Stream<T> stream(T[] array)
IntStream stream = Arrays.stream(arr);
Person cul = new Person("Cul", 33);
Person tim = new Person("Tim", 54);
Person[] pArr = new Person[]{cul,tim};
Stream<Person> personStream = Arrays.stream(pArr);
}
3. Stream.of()
@Test
public void test3(){
Stream<String> stream = Stream.of("abc", "acb", "bac", "cab");
}
4. 创建无限流
@Test
public void test4(){
//迭代
// public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
//seed为初始值
Stream.iterate(0, t -> t + 2).limit(10);
//生成
//public static<T> Stream<T> generate(Supplier<T> s)
Stream.generate(Math::random).limit(10);
}
Stream中间操作
中间操作不会执行任何的处理,而在终止操作时一次型全部处理,称为“惰性求值”。
1. 筛选与切片
方法 | 描述 |
---|---|
filter(Predicate p) | 接收lambda,从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 |
limit(long maxSize) | 截断流,使其元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前n个元素的流, 若流中元素不足n个,则返回一个空流,与limit(n)互补 |
@Test
public void test1(){
List<Person> list = getPersonList();
//filter() 排除某些元素
list.stream().filter(person -> person.getAge()<30).forEach(System.out::println);
//limit() 截取前n个元素
list.stream().limit(2).forEach(System.out::println);
System.out.println("******");
//skip(n) 跳过前n个元素
list.stream().skip(2).forEach(System.out::println);
//distinct() 根据hashCode和equals方法去重
list.add(new Person("Tom",20));
list.add(new Person("Tom",20));
System.out.println("******");
list.stream().distinct().forEach(System.out::println);
}
2. 映射
方法 | 描述 |
---|---|
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上, 并将其映射成一个新的元素 |
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上, 产生一个新的DoubleStream |
mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上, 产生一个新的IntStream |
mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上, 产生一个新的LongStream |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。 |
@Test
public void test2(){
//1.map(Function f)
List<String> list = Arrays.asList("ad,az,df,ss,as,df");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
List<Double> list1 = Arrays.asList(30.0, 45.0, 90.0, 135.0, 180.0);
list1.stream().map(Math::cos).forEach(System.out::println);
//获取person name的length>3的name
List<Person> personList = getPersonList();
personList.stream().map(Person::getName).filter(name -> name.length() > 3).forEach(System.out::println);
//2.flatMap(function f)类比list.add()和list.addAll()
List<String> list2 = Arrays.asList("ad", "aa", "aj", "ak");
list2.stream().flatMap(StreamMidOperate::trans).forEach(System.out::println);
}
public static Stream<Character> trans(String str){
List<Character> list = new ArrayList<>();
for (Character c : str.toCharArray()){
list.add(c);
}
return list.stream();
}
3. 排序
方法 | 描述 |
---|---|
sorted() | 产生一个新流,其中按自然顺序排序 |
sorted(Comparator com) | 产生一个新流,其中按比较器顺序排序 |
@Test
public void test3(){
//sorted() 自然排序
List<Integer> list = Arrays.asList(2, 31, 4, 21, 9, 23, 45, 33);
list.stream().sorted().forEach(System.out::println);
//sorted(Comparator c) 自定义
List<Person> personList = getPersonList();
personList.stream().sorted(Comparator.comparingInt(Person::getAge))
.forEach(System.out::println);
}
Stream终止操作
流进行了终止操作后,不能再次使用
1. 匹配与查找
方法 | 描述 |
---|---|
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count() | 返回流中元素总数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代 |
@Test
public void test1(){
List<Person> list = getPerson();
//allMatch(Predicate p) 是否所有的元素都满足条件
//所有person的age是否都大于18
boolean allMatch = list.stream().allMatch(p -> p.getAge() > 18);
System.out.println(allMatch);
//anyMatch(Predicate p) 是否有一个元素满足条件
boolean anyMatch = list.stream().anyMatch(p -> p.getName().contains("a"));
System.out.println(anyMatch);
//noneMatch(Predicate p) 是否没有元素匹配
boolean noneMatch = list.stream().noneMatch(p -> p.getName().length() > 6);
System.out.println(noneMatch);
//findFirst() 返回第一个元素
Optional<Person> first = list.stream().findFirst();
Person person = first.get();
System.out.println(person);
//findAny 返回任意元素
Optional<Person> any = list.parallelStream().findAny();
System.out.println(any);
}
@Test
public void test2(){
List<Person> list = getPerson();
//count()返回流中元素的总个数
long count = list.stream().filter(p -> p.getAge() > 25).count();
System.out.println(count);
//max(Comparator c) 返回流中最大值
Optional<Integer> max = list.stream().map(Person::getAge).max(Integer::compare);
System.out.println(max);
//min(Comparator c) 返回流中最小值
Optional<Person> min = list.stream().min(Comparator.comparingInt(Person::getAge));
System.out.println(min);
//foreach() 内部迭代
list.stream().forEach(System.out::println);
}
2. 归约
方法 | 描述 |
---|---|
reduce(T iden,BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值,返回T |
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值,返回Optional<T> |
@Test
public void test3(){
//reduce(T iden,BinaryOperator b)
List<Integer> list = Arrays.asList(10,2,8,7,3,4,6);
Integer sum = list.stream().reduce(0, Integer::sum);//identity为sum的基础值
System.out.println(sum);
List<Person> personList = getPerson();
//reduce(BinaryOperator b)
//Optional<String> reduce = personList.stream().map(Person::getId).reduce(String::concat);//获取所有id,并将id连接起来
Optional<String> reduce = personList.stream().map(Person::getId).reduce((s1,s2) -> s1 + "," + s2);//获取所有id,并将id连接起来
System.out.println(reduce);
}
3.收集
方法 | 描述 |
---|---|
collect(Collector c) | 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法 |
Collectors提供了一些方法,创建常见的List、Set、Map等。
@Test
public void test4(){
//collect(Collector c)
List<Person> list = getPerson();
//Set<Person> collect = list.stream().filter(p -> p.getAge() > 30).collect(Collectors.toSet());
List<Person> collect = list.stream().filter(p -> p.getAge() > 30).collect(Collectors.toList());
collect.forEach(System.out::println);
}
关于将list集合转换为Map
转换为HashMap
Person类:
public class Person {
private String id;
private String name;
private Integer age;
//...
}
Collectors的toMap方法
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
//T 输入元素
//K key映射函数的输出类型
//U value映射汗的输出类型
//keyMapper 产生key的映射函数
//valueMapper 产生value的映射函数
实例:
List<Person> list = new ArrayList<Person>();
list.add(new Person(...))
//...添加person元素
list.stream()
.filter(p -> p.getName().contains("i"))//过滤
.collection(Collectors.toMap(Person::getId,p->p))//收集
.forEach((k,v)->System.out.println(k + ":" + v))
转换为LinkedHashMap
//Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
// Function<? super T, ? extends U> valueMapper,
// BinaryOperator<U> mergeFunction,
// Supplier<M> mapSupplier) {
LinkedHashMap<String, Person> collect2 = list.stream()
.collect(
Collectors.toMap(Person::getId,//返回key
p -> p,//返回value
(p1, p2) -> {
Objects.requireNonNull(p1);
Objects.requireNonNull(p2);
if (p1.getId().equals(p2.getId())) {
return p2;
}
return p1;
},//对于相同key如何处理
LinkedHashMap::new));//产生LinkedHashMap
collect2.forEach((k,v) -> {
System.out.println(k + ":" + v);
});
最后
以上就是阔达裙子为你收集整理的StreamAPI基本使用StreamAPI的全部内容,希望文章能够帮你解决StreamAPI基本使用StreamAPI所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复