Stream
Stream也叫Stream流,是JDK8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据
优势
Stream流大量地结合了Lambda地语法风格来编程,提供了一种更加强大、更加简单的方式操作集合或数组中的数据,代码更简洁,可读性更好
Stream流的获取
获取集合的Stream流:
Collection提供的方法 | 说明 |
---|---|
default Stream stream() | 获取当前集合对象的Stream流 |
获取数组的Stream流:
Arrays类提供的方法 | 说明 |
---|---|
public static Stream stream(T[] array) | 获取当前数组的Stream流 |
Stream类提供的方法 | 说明 |
---|---|
public static Stream of(T… values) | 获取当前接收数据的Stream流 |
案例演示
public class StreamTest1 {
public static void main(String[] args) {
//获取List集合的Stream流
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "灭绝");
Stream<String> stream = names.stream();
//获取Set集合的Stream流
Set<String> set = new HashSet<>();
Collections.addAll(set, "劫", "艾希", "索拉卡", "卡兹克", "迦娜");
Stream<String> stream1 = set.stream();
stream1.filter(s -> s.contains("卡")).forEach(s -> System.out.println(s));
//获取Map集合的Stream流
Map<String, Integer> map = new HashMap<>();
map.put("盖伦", 182);
map.put("嘉文四世", 185);
map.put("赵信", 186);
map.put("卡特琳娜", 165);
//方法1:获取Map的键和值,分别获取他们的stream流
Set<String> key = map.keySet();
Stream<String> ks = key.stream();
Collection<Integer> values = map.values();
Stream<Integer> vs = values.stream();
//方法2:利用Set<Map.Entry<K, V>> entrySet()方法将Map集合的键值对保存到Set集合
//再通过Stream<Map.Entry<K, V>> stream()方法获取其stream流
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Stream<Map.Entry<String, Integer>> stream2 = entries.stream();
stream2.filter(k -> k.getKey().contains("娜")).forEach(k -> System.out.println(k.getKey() + ":" + k.getValue()));
//数组获取Stream流
String[] names2 = {"艾克", "艾瑞利亚", "泰隆", "崔丝塔娜", "卡莉斯塔"};
//方法1:使用Arrays提供的方法Arrays.stream()方法获取数组的stream流
Stream<String> stream3 = Arrays.stream(names2);
//方法2:使用Stream的Stream.of()方法获取数组的stream流
Stream<String> stream4 = Stream.of(names2);
stream3.forEach(s -> System.out.println(s));
}
}
Stream流常见的中间方法
中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)
Stream提供的常用中间方法 | 说明 |
---|---|
Stream<T> filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤 |
Stream<T> sorted() | 对元素进行升序排序 |
Stream<T> sorted(Comparator<? super T> comparator) | 按照指定规则排序 |
Stream<T> limit(long maxSize) | 获取前几个元素 |
Stream<T> skip(long n) | 跳过前几个元素 |
Stream<T> distinct() | 去除流中重复的元素 |
<R> Stream map(Function<? super T, ? extends R> mapper) | 对元素进行加工,并返回对应的新流 |
static Stream concat(Stream a, Stream b) | 将ab两个流合并为一个流 |
案例演示
public class StreamTest2 {
public static void main(String[] args) {
List<Double> scores = new ArrayList<>();
Collections.addAll(scores, 70.0, 88.5, 99.5, 56.0, 65.5, 97.0, 86.5);
//找出成绩大于70分的数据,升序输出
//filter过滤筛选,sorted升序,终结方法forEach:对此流运算后的元素执行遍历
Stream<Double> doubleStream = scores.stream();
doubleStream.filter(s -> s >= 70).sorted().forEach(s -> System.out.print(s + " "));
doubleStream.close();
System.out.println();
List<Person> persons = new ArrayList<>();
Person p1 = new Person("亚托克斯", 40, 385.0);
Person p2 = new Person("提莫", 16, 81.0);
Person p3 = new Person("佐伊", 23, 139.0);
Person p4 = new Person("卡特琳娜", 26, 178.0);
Person p5 = new Person("泰达米尔", 30, 191.0);
Person p6 = new Person("泰达米尔", 30, 191.0);
Person p7 = new Person("艾希", 27, 170.0);
Collections.addAll(persons, p1, p2, p3, p4, p5, p6);
// Stream<Person> personStream = persons.stream();
//找出年龄大于23且小于等于30岁的英雄,并按照年龄降序输出
//filter筛选,sorted排序
persons.stream().filter(p -> p.getAge() > 23 && p.getAge() <= 30).sorted((o1, o2) -> o2.getAge() - o1.getAge()).forEach(o -> System.out.println(o));
//取出身高最高的3名英雄,并输出
System.out.println("--------------------------");
//同上,limit获取前几个元素
persons.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight())).limit(3).forEach(o -> System.out.println(o));
//取出身高倒数的2名英雄,并输出
System.out.println("--------------------------");
//skip跳过前几个元素
persons.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight())).skip(persons.size() - 2).forEach(System.out::println);
//找出身高超过160的学生叫什么名字,要求去除重复的名字,再输出
System.out.println("--------------------------");
//map加工,使得输出流只剩对象名
persons.stream().filter(o -> o.getHeight() > 160).map(o -> o.getName()).distinct().forEach(System.out::println);
Stream<String> str1 = Stream.of("李华", "李雷", "韩梅梅");
Stream<String> str2 = Stream.of("张晓明", "黄嘉欣", "赵凯");
Stream<String> allSt = Stream.concat(str1, str2);
allSt.forEach(System.out::println);
}
}
Stream流常见的终结方法
终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了
Stream提供的常用终结方法 | 说明 |
---|---|
void forEach(Consumer action) | 对此流运算后的元素执行遍历 |
long count | 统计此流运算后的元素个数 |
Optional max(Comparator<? super T> comparator) | 获取此流运算后的最大值元素 |
Optional min(Comparator<? super T> comparator) | 获取此流运算后的最小值元素 |
收集Stream流
把Stream流操作后的结果转回到集合或数组中去返回
Stream流是方便操作集合/数组的手段,而集合/数组才是开发中的目的
收集Stream流的方法 | 说明 |
---|---|
R collect(Collectors collector) | 把流处理后的结果收集到一个指定的集合中去 |
Object[] toArray() | 把流处理后的结果收集到一个数组中去 |
案例演示
public class StreamTest3 {
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
Person p1 = new Person("亚托克斯", 40, 385.0);
Person p2 = new Person("提莫", 16, 81.0);
Person p3 = new Person("佐伊", 23, 139.0);
Person p4 = new Person("卡特琳娜", 26, 178.0);
Person p5 = new Person("泰达米尔", 30, 191.0);
Person p6 = new Person("艾希", 27, 170.0);
Collections.addAll(persons, p1, p2, p3, p4, p5, p6);
//计算出身高超过168的有几人
System.out.println(persons.stream().filter(o -> o.getHeight() >= 168).count());
//找出身高最高的对象,并输出
System.out.println(persons.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get());
//找出身高最矮的对象,并输出
Person p7 = persons.stream().min(((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()))).get();
System.out.println(p7);
System.out.println("---------------------");
//找出身高超过170的对象,并放到一个新集合中去返回
List<Person> list = persons.stream().filter(o -> o.getHeight() >= 170).collect(Collectors.toList());
list.stream().forEach(System.out::println);
System.out.println("------------------------");
Set<Person> set = persons.stream().filter(o -> o.getHeight() >= 170).collect(Collectors.toSet());
set.stream().forEach(System.out::println);
//找出身高超过170的对象,并把对象的名字和身高存入到一个Map集合返回
System.out.println("------------------------------------------------------------");
Map<String, Double> map = persons.stream().filter(o -> o.getHeight() >= 170).collect(Collectors.toMap(n -> n.getName(), n -> n.getHeight()));
System.out.println(map);
//找出身高超过170的对象,并把对象的名字和身高存入到一个数组返回
System.out.println("----------------------------------------------------------------------------");
Object[] objects = persons.stream().filter(o -> o.getHeight() >= 170).toArray();
System.out.println(Arrays.toString(objects));
System.out.println("----------------------------------------------------------------------------");
Person[] people = persons.stream().filter(o -> o.getHeight() >= 170).toArray(len ->new Person[len]);
System.out.println(Arrays.toString(people));
}
}