Stream流入门
Jdk8开始新增的一套API,可以用于操作集合或者数组的数据。
优势: Stream流大量地结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好。
//获取姓张且名字是三个字的人名
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰","周芷若","赵强","张三","张一二");
//集合做法
List<String> temp = new ArrayList<>();
for (String name : names) {
if (name.startsWith("张") && name.length() == 3)
temp.add(name);
}
System.out.println(temp);
//Stream流方法
//filter过滤,collect收集
//names.stream().filter(s -> s.startsWith("张") && s.length() == 3);
List<String> list = names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3)
.collect(Collectors.toList());
System.out.println(list);
}
}
相比之下利用Stream流使用一行代码就搞定了功能需求。
总之可以把使用Stream流看作是以下过程。
public interface Stream<T> extends BaseStream<T, Stream<T>> {}
Stream本身是一个接口,不能直接创建对象。而且与数据源有关,不会凭空创造一个流出来不处理数据。
- 集合的数据流:
default Stream stream() :获取当前集合的数据流 - 数组的数据流:
Arrays类提供了public static Stream stream(T[] array) : 获取数组的数据流
Stream类提供了public static Stream of(T… values) : 获取当前数据的数据流
public class Main {
public static void main(String[] args) {
//list
List<String> list = new ArrayList<>();
Collections.addAll(list, "张三丰","周芷若","赵强","张三","张一二");
Stream<String> stream = list.stream();
stream.filter(s -> s.startsWith("张")).forEach(System.out::println);
//set
Set<String> set = new HashSet<>();
Collections.addAll(set, "张三丰","周芷若","赵强","张三","张一二");
Stream<String> stream1 = set.stream();
stream1.filter(s -> s.startsWith("张")).forEach(System.out::println);
//map不能直接用stream()创建流,因为方法stream()是Collection接口提供的
Map<String, Integer> map = new HashMap<>();
map.put("张三丰", 1);
map.put("周芷若", 2);
map.put("赵强", 3);
map.put("张三", 4);
map.put("张一二", 5);
Set<Map.Entry<String, Integer>> entries = map.entrySet();
entries.stream().filter(s -> s.getKey().startsWith("张")).forEach(System.out::println);
//数组
String[] strings = {"张三丰","周芷若","赵强","张三","张一二"};
Stream<String> stream2 = Arrays.stream(strings);
Stream<String> stream3 = Stream.of(strings);
}
}
常用中间方法
中间方法:调用完后会返回新的Stream流,可以继续被使用(支持链式编程)。
注意的是使用distinct()方法去重复时,如果是自定义类需要重写自定义类的hashcode()和equals()方法。(idea里Alt+insert自动生成)
仅对后两个距离,其他和filter()差不多。
public class Main {
public static void main(String[] args) {
//list
List<String> list = new ArrayList<>();
Collections.addAll(list, "张三丰","周芷若","赵强","张三","张一二");
Stream<String> stream = list.stream();
//map相当于一个映射,对流里面的每一个元素处理之后再放回去
stream.filter(s -> s.startsWith("张")).map(s -> "new" + s).forEach(System.out::println);
/*
new张三丰
new张三
new张一二
*/
//注意如果类型不一样,返回的是Object
Stream<Integer> stream1 = Stream.of(1, 2);
Stream<Integer> stream2 = Stream.of(3, 4, 5);
Stream.concat(stream2, stream1).forEach(System.out::println);//3 4 5 1 2
}
}
常用终结方法
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 23,43,35,14,65);
long num = list.stream().filter(s -> s > 20).count();
System.out.println(num);
//max和min返回Optional<T>容器,用get()从容器中拿出来
//stream.filter(s -> s > 20).max((o1, o2) -> Integer.compare(o1, o2));
Integer max = list.stream().filter(s -> s > 20).max(Integer::compareTo).get();
System.out.println(max);
Integer min = list.stream().filter(s -> s > 20).min(Integer::compareTo).get();
System.out.println(min);
}
}
使用Stream流还有一点最重要的是收集Stream流,把处理好的数据返回。
public class Main {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
Student stu1 = new Student("王五", 40);
Student stu2 = new Student("李四", 30);
Student stu3 = new Student("王五", 40);
Collections.addAll(list, stu1, stu2, stu3);
List<Student> collect = list.stream().filter(s -> s.getAge() >= 30).collect(Collectors.toList());
System.out.println(collect);
Set<Student> collect1 = list.stream().filter(s -> s.getAge() >= 30).collect(Collectors.toSet());
System.out.println(collect1);
Map<String, Integer> map = list.stream().filter(s -> s.getAge() >= 30)
.distinct()//Student类重写了hashcode()和equals()方法
.collect(Collectors.toMap(Student::getName, Student::getAge));
System.out.println(map);
//返回数组
Object[] objects = list.stream().filter(s -> s.getAge() >= 30).toArray();
//Student[] students = list.stream().filter(s -> s.getAge() >= 30).toArray(len -> new Student[len]);
Student[] students = list.stream().filter(s -> s.getAge() >= 30).toArray(Student[]::new);
System.out.println(Arrays.toString(students));
}
}