Stream目录
JDK 8中的Stream是对集合对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作。在JDK 8中使用Stream,代码更加简洁易读;而且使用并发模式,程序执行速度更快。
Stream的构造与转换
// 1. Arrays -> Stream
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays -> Stream
String [] strArray = new String[] {"a", "b", "c"};
Stream stream = Stream.of(strArray);
// 或者 Stream stream = Arrays.stream(strArray);
// 3. Arrays -> Collections -> Stream
List<String> list = Arrays.asList(strArray);
Stream stream = list.stream();
// 4. Collections -> Stream
List<String> list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
Stream stream = list.stream();
包装类型Stream
对于基本数值型,目前有三种对应的包装类型Stream:IntStream、LongStream、DoubleStream。当然我们也可以用 Stream、Stream、Stream,但是 boxing 和 unboxing 会很耗时,所以特别为这三种基本数值型提供了对应的 Stream
Stream转换为其它数据结构
// 1. Array
String[] strArray1 = stream.toArray(String[]::new);
// 2. Collection
List<String> list1 = stream.collect(Collectors.toList()); // list
List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new)); // 指定ArrayList
Set set1 = stream.collect(Collectors.toSet()); // set
Stack stack1 = stream.collect(Collectors.toCollection(Stack::new)); // Stack
// 3. Map
Map<String, Test> testMap1 = stream.collect(Collectors.toMap(Test::getId, test -> test)); // Map<String, Test>
Map<String, String> testMap2 = stream.collect(Collectors.toMap(Test::getId, Test::getName)); // Map<String, String>
// 4. String
String str = stream.collect(Collectors.joining()).toString();
map(映射转换)
- 字符串装换成大写的字符
List<String> output = wordList.stream().map(String::toUpperCase).collect(Collectors.toList());
- 求平方
List<Integer> nums = Arrays.asList(1, 2, 3, 4);
List<Integer> squareNums = nums.stream().map(n -> n * n).collect(Collectors.toList());
filter(过滤)
在filter中边写过滤的条件
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
Integer[] evens = list.stream().filter(n -> n > 3).toArray(Integer[]::new);
foreach(for循环)
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
list.stream().filter(n -> n > 3).forEach(p -> System.out.println(p));
reduce(规则计算)
根据一定的规则将Stream中的元素进行计算后返回一个唯一的值
- 求和
int sum1 = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum); // 无起始值
int sum2 = Stream.of(1, 2, 3, 4).reduce(10, Integer::sum); // 有起始值
- 字符串拼接
String concat = Stream.of("a", "b", "c", "d").reduce("", String::concat);
- 最大值
int max = Stream.of(10, 30, 40, 5).reduce(Integer.MIN_VALUE, Integer::max);
- 最小值
double min = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
limit(截取前n个元素)
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
List<Integer> collect = list.stream().limit(5).collect(Collectors.toList());
skip(丢弃取前n个元素)
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
List<Integer> collect = list.stream().skip(3).collect(Collectors.toList());
sorted(排序)
/**
* 从小到大排序
*/
@Data
@AllArgsConstructor
static class Person implements Comparable {
public int id;
private String name;
@Override
public int compareTo(Object o) {
return 0;
}
}
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
Person person = new Person(i, "name" + i);
if (i == 2) {
person.setId(10);
}
persons.add(person);
}
persons.stream().forEach(p -> System.out.println(p));
persons.stream().sorted(Comparator.comparing(Person::getId)).forEach(p -> System.out.println(p));
}
/**
* 从大到小排序
*/
@Data
@AllArgsConstructor
static class Person implements Comparable {
public int id;
private String name;
@Override
public int compareTo(Object o) {
return 0;
}
}
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
Person person = new Person(i, "name" + i);
if (i == 2) {
person.setId(10);
}
persons.add(person);
}
persons.stream().forEach(p -> System.out.println(p));
persons.stream().sorted(Comparator.comparing(Person::getId).reversed()).forEach(p -> System.out.println(p));
}
max/min(最大值/最小值)
List<Student> students = new ArrayList<>(3);
students.add(new Student("路飞", 22, 175));
students.add(new Student("红发", 40, 180));
students.add(new Student("白胡子", 50, 185));
Optional<Student> max = students.stream()
.max(Comparator.comparing(stu -> stu.getAge()));
Optional<Student> min = students.stream()
.min(Comparator.comparing(stu -> stu.getAge()));
//判断是否有值
if (max.isPresent()) {
System.out.println(max.get());
}
if (min.isPresent()) {
System.out.println(min.get());
}
count(计数)
一般都是结合filter使用,因为先筛选出我们需要的再统计即可。及早求值
List<Student> students = new ArrayList<>(3);
students.add(new Student("张三", 22, 175));
students.add(new Student("李四", 40, 180));
students.add(new Student("王五", 50, 185));
long count = students.stream().filter(student -> student.getAge() < 30).count();
groupingBy(分组)
根据年龄分组
List<Student> students = new ArrayList<>(4);
students.add(new Student("张三", 22, 175));
students.add(new Student("李四", 22, 170));
students.add(new Student("王五", 40, 180));
students.add(new Student("赵六", 50, 185));
Map<Integer, List<Student>> listMap = students.stream().collect(
Collectors.groupingBy(student -> student.getAge()));
partitioningBy(划分)
根据年龄是否<30岁来划分
List<Student> students = new ArrayList<>(4);
students.add(new Student("张三", 22, 175));
students.add(new Student("李四", 22, 170));
students.add(new Student("王五", 40, 180));
students.add(new Student("赵六", 50, 185));
Map<Boolean, List<Student>> collect = students.stream().collect(
Collectors.partitioningBy(student -> student.getAge() < 30));