创建实体类Author
package com.zsh.stream.domain.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode// 用于后期的去重使用
public class Author {
// id
private Long id;
// 姓名
private String name;
// 年龄
private Integer age;
// 简介
private String intro;
// 作品
private List books;
}
创建实体类Book
package com.zsh.stream.domain.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode// 用于后期的去重使用
public class Book {
// id
private Long id;
// 书名
private String name;
// 分类
private String category;
// 评分
private Integer score;
// 简介
private String Intro;
}
创建测试类
package com.zsh.stream.demo;
import com.zsh.stream.domain.po.Author;
import com.zsh.stream.domain.po.Book;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo {
/**
* 数据准备
* @return
*/
private static List getAuthors() {
// 数据初始化
Author author1 = new Author(1L, "开朗觉觉", 16, "30年超级Java开发工程师", null);
Author author2 = new Author(1L, "开朗觉觉", 16, "30年超级Java开发工程师", null);
Author author3 = new Author(3L, "小美", 17, "10年超级Java开发工程师", null);
Author author4 = new Author(4L, "觉觉", 19, "5年超级Java开发工程师", null);
// 书籍列表
ArrayList books1 = new ArrayList<>();
ArrayList books2 = new ArrayList<>();
ArrayList books3 = new ArrayList<>();
books1.add(new Book(1L,"晨岛快速跑图攻略1","哲学",88,"123123"));
books1.add(new Book(2L,"晨岛快速跑图攻略2","哲学",88,"123123"));
books1.add(new Book(3L,"晨岛快速跑图攻略2","哲学",88,"123123"));
books2.add(new Book(1L,"晨岛快速跑图攻略1","哲学",88,"123123"));
books2.add(new Book(2L,"晨岛快速跑图攻略2","哲学",88,"123123"));
books2.add(new Book(3L,"晨岛快速跑图攻略2","哲学",88,"123123"));
books3.add(new Book(7L,"晨岛快速跑图攻略3","哲学",88,"123123"));
books3.add(new Book(8L,"晨岛快速跑图攻略3","哲学",88,"123123"));
books3.add(new Book(9L,"晨岛快速跑图攻略3","哲学",88,"123123"));
author1.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
ArrayList authorList = new ArrayList<>(Arrays.asList(author1,author2,author3,author4));
return authorList;
}
}
public class StreamDemo {
public static void main(String[] args) {
// 打印年龄小于18的作家名字,并且去重
test1();
}
/**
* 打印年龄小于18的作家名字,并且去重
*/
private static void test1() {
// 数据准备
List authors = getAuthors();
// 打印年龄小于18的作家名字,并且去重
authors.stream() // 把集合转换成流
// 去重
.distinct()
// 筛选
.filter(author -> author.getAge() < 18)
// 打印
.forEach(author -> System.out.println(author.getName()));
}
}
public class StreamDemo {
public static void main(String[] args) {
// 单列集合创建流(重要)
test2();
}
/**
* 单列集合创建流
*/
private static void test2() {
// 数据准备
List authors = getAuthors();
// 单列集合创建流
Stream stream = authors.stream();
}
}
public class StreamDemo {
public static void main(String[] args) {
// 数组创建流(方式1)
test3();
// 数组创建流(方式2)
test4();
}
/**
* 数组创建流(方式2)
*/
private static void test4() {
// 创建数组
Integer[] numArr = {1,2,3,4,5};
// 数组创建流
Stream stream = Stream.of(numArr);
// 输出
stream.filter(integer -> integer > 2)
.forEach(integer -> System.out.println(integer));
}
/**
* 数组创建流(方式1)
*/
private static void test3() {
// 创建数组
Integer[] numArr = {1,2,3,4,5};
// 数组创建流
Stream stream = Arrays.stream(numArr);
// 输出
stream.filter(integer -> integer % 2 == 0)
.forEach(integer -> System.out.println(integer));
}
}
public class StreamDemo {
public static void main(String[] args) {
// Map创建流
test5();
}
/**
* Map创建流
*/
private static void test5() {
HashMap map = new HashMap<>();
map.put("开朗觉觉",16);
map.put("开朗莽莽",17);
map.put("酪小美",18);
// 将Map集合转换为Set集合 (Map集合是不能直接转换为Stream流的,所以要先转成Set集合)
Set> entrySet = map.entrySet();
// 创建Stream流
Stream> stream = entrySet.stream();
// 输出
stream.filter(item -> item.getValue() == 18)
.forEach(item -> System.out.println(item.getKey() + "," + item.getValue() + "岁"));
}
}
public class StreamCenter {
public static void main(String[] args) {
// filter() 打印所有名字长度大于2的作家姓名
test1();
}
/**
* filter() 打印所有名字长度大于2的作家姓名
*/
private static void test1() {
// 数据准备
List authors = getAuthors();
// 获取流并打印
authors.stream()
.distinct()
.filter(author -> author.getName().length() > 2)
.forEach(author -> System.out.println(author.getName()));
}
}
public class StreamCenter {
public static void main(String[] args) {
// map() 将流中的元素进行转换
test2();
}
/**
* map() 将流中的元素进行转换
*/
private static void test2() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.map(author -> author.getName())
.forEach(name -> System.out.println(name));
}
}
public class StreamCenter {
public static void main(String[] args) {
// map() 将流中元素进行计算
test3();
}
/**
* map() 将流中元素进行计算
*/
private static void test3() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.map(author -> author.getAge())
.map(age -> age + 10)
.forEach(System.out::println);
}
}
将返回类型改为Int,后续进行数据操作可以避免拆箱装箱,增加效率
private static void test10() {
List authors = getAuthors();
authors.stream()
// 将值的返回类型改为Int,后续进行数据操作可以避免拆箱装箱,增加效率
.mapToInt(author -> author.getAge())
.map(age -> age + 10)
.filter(age -> age > 18)
.map(age -> age + 2)
.forEach(System.out::println);
}
与mapToInt()类似,参照mapToInt();
与mapToInt()类似,参照mapToInt();
注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以注意重写equals方法;
public class StreamCenter {
public static void main(String[] args) {
// distinct() 去除重复元素 (distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以注意重写equals方法)
test4();
}
/**
* distinct() 去除重复元素 (distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以注意重写equals方法)
*/
private static void test4() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.distinct()
.forEach(author -> System.out.println(author.getName()));
}
}
注意:如果调用空参的sorted方法,需要流中的元素是实现了Comparable;
public class StreamCenter {
public static void main(String[] args) {
// sorted() 对流中的元素按年龄进行排序 (注意如果调用空参的sorted方法,需要流中的元素是实现了Comparable)
test5();
}
/**
* sorted() 对流中的元素按年龄进行排序
*/
private static void test5() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.forEach(author -> System.out.println(author.getName() + "," + author.getAge()));
}
}
注意:超出的部将被抛弃;
public class StreamCenter {
public static void main(String[] args) {
// limit() 对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中两个年龄最大的作家
test6();
}
/**
* limit() 对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中两个年龄最大的作家
*/
private static void test6() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.distinct()
.sorted((o1, o2) -> o2.getAge() - o1.getAge())
.limit(2)
.forEach(author -> System.out.println(author.getName() + "," + author.getAge()));
}
}
public class StreamCenter {
public static void main(String[] args) {
// skip() 跳过流中的几个元素
test7();
}
// skip() 跳过流中的几个元素
private static void test7() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.skip(1)
.forEach(author -> System.out.println(author.getName()));
}
}
public class StreamCenter {
public static void main(String[] args) {
// flatMap() 将流中元素的多个对象作为流中的元素
test8();
}
/**
* flatMap() 将流中元素的多个对象作为流中的元素
*/
private static void test8() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.forEach(book -> System.out.println(book.getName()));
}
}
打印现有数据的所有分类,要求去重,不能出现连着的分类:哲学,爱情
public class StreamCenter {
public static void main(String[] args) {
// 打印现有数据的所有分类,要求去重,不能出现连着的分类:哲学,爱情
test9();
}
/**
* 打印现有数据的所有分类,要求去重,不能出现连着的分类:哲学,爱情
*/
private static void test9() {
// 数据准备
List authors = getAuthors();
// 创建流并输出
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.flatMap(book -> Arrays.stream(book.getCategory().split(",")))
.distinct()
.forEach(category -> System.out.println(category));
}
}
parallel() 将串行的流改为并行的流,多线程操作
private static void test11() {
// parallel() 将串行的流改为并行的流,多线程操作
List authors = getAuthors();
authors.stream()
.parallel()
.map(author -> author.getName())
.forEach(name -> System.out.println(name + " " + Thread.currentThread().getName()));
}
parallelStream() 直接的并行流对象,将串行的流改为并行的流,多线程操作
private static void test12() {
// parallelStream() 直接的并行流对象,将串行的流改为并行的流,多线程操作
List authors = getAuthors();
authors.parallelStream()
.map(author -> author.getName())
.forEach(name -> System.out.println(name + " " + Thread.currentThread().getName()));
}
对流中的元素进行遍历操作,通过传入传入的参数去指定对遍历的元素进行什么具体操作;
private static void test01(List authors) {
// 打印所有作家的名字,注意删除重复元素
authors.stream()
// 将流中的元素进行转换,并返回
.map(author -> author.getName())
// 去重
.distinct()
// 遍历流中的元素
.forEach(System.out::println);
}
private static void test02(List authors) {
// 打印作家所出的书籍的数目,注意删除重复元素
long count = authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.count();
// 输出
System.out.println(count);
}
private static void test03(List authors) {
// 获取这些作家分数最高和最低的书籍
Optional max = authors.stream()
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.max((score1, score2) -> score1 - score2);
System.out.println("最大值:" + max.get());
Optional min = authors.stream()
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getScore())
.min((score1, score2) -> score1 - score2);
System.out.println("最小值:" + min.get());
}
List集合
private static void test04(List authors) {
// 获取一个存放所有作者名字的List集合
List nameList = authors.stream()
.map(author -> author.getName())
.collect(Collectors.toList());
System.out.println(nameList);
}
set集合
private static void test05(List authors) {
// 获取一个所有书名的Set集合
Set bookNameSet = authors.stream()
.flatMap(author -> author.getBooks().stream())
.map(book -> book.getName())
.collect(Collectors.toSet());
System.out.println(bookNameSet);
}
map集合
注意map集合的key值不能重复
private static void test06(List authors) {
// 获取一个map集合,key是作者名,value是书名的list集合
Map> nameAndBookNameMap = authors.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
}
anyMatch() 和filter()的区别:
filter():根据条件过滤流中的元素,符合条件的继续往下走
anyMatch():根据条件判断,是否有符合条件的元素,有则返回true,没有返回false
private static void test07(List authors) {
// 判断是否有年龄在29以上的作家
boolean okAndNo = authors.stream()
.anyMatch(author -> author.getAge() > 29);
System.out.println(okAndNo);
}
private static void test08(List authors) {
// 判断作家是否都是成年人
boolean okAndNo = authors.stream()
.allMatch(author -> author.getAge() >= 18);
System.out.println(okAndNo);
}
private static void test09(List authors) {
// 判断作家是否都没超过100岁
boolean okAndNo = authors.stream()
.noneMatch(author -> author.getAge() > 100);
System.out.println(okAndNo);
}
private static void test10(List authors) {
// 获取任意一个年龄大于18的作家,如果存在就输出名字
Optional authorOptional = authors.stream()
.filter(author -> author.getAge() > 18)
.findAny();
authorOptional.ifPresent(author -> System.out.println(author.getName()));
}
private static void test11(List authors) {
// 获取一个年龄最小的作家,并输出他的名字
Optional minAge = authors.stream()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.findFirst();
minAge.ifPresent(author -> System.out.println(author.getName()));
}
reduce两个参数的重载形式内部的计算方式如下:
T result = identity;
for (T element : this stream) {
result = accumulator.apply(result,element)
}
return result;
求所有作家的年龄和
public class StreamEnd {
public static void main(String[] args) {
// reduce() 对流中的数据按照你指定的计算方式计算出一个结果
// 求所有作家的年龄和
// test12(authors);
}
/**
* reduce() 对流中的数据按照你指定的计算方式计算出一个结果
* @param authors
*/
private static void test12(List authors) {
// 求所有作家的年龄和
Integer avgSum = authors.stream()
.map(author -> author.getAge())
.reduce(0, (result, element) -> result + element);
System.out.println(avgSum);
}
}
求所有作家中年龄最大的值
public class StreamEnd {
public static void main(String[] args) {
// 求所有作家中年龄最大的值
test13(authors);
}
/**
* reduce() 对流中的数据按照你指定的计算方式计算出一个结果
* @param authors
*/
private static void test13(List authors) {
// 求所有作家中年龄最大的值
Integer ageMax = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
System.out.println(ageMax);
}
}
求作家中年龄的最小值
public class StreamEnd {
public static void main(String[] args) {
// 求所有作家中年龄最大的值
test14(authors);
}
/**
* reduce() 对流中的数据按照你指定的计算方式计算出一个结果
* @param authors
*/
private static void test14(List authors) {
// 求作家中年龄的最小值
Integer ageMin = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MAX_VALUE, (result, element) -> result < element ? result : element);
System.out.println(ageMin);
}
}
reduce一个参数的重载形式内部的计算
这个就相当于是把第一个元素值当成默认值来用(要注意,不要为为出现空值)
boolean foundAny = false;
T result = null;
for (T element : this stream) {
if (!foundAny) {
foundAny = true;
result = element;
} else {
result = accumulator.apply(result,element);
}
}
return foundAny ? Optional.of(result) : Optional.empty();
用一个参数的reduce求作家中年龄的最小值
public class StreamEnd {
public static void main(String[] args) {
// 用一个参数的reduce求作家中年龄的最小值
test15(authors);
}
/**
* reduce() 对流中的数据按照你指定的计算方式计算出一个结果
* @param authors
*/
private static void test15(List authors) {
// 用一个参数的reduce求作家中年龄的最小值
Optional authorsOptional = authors.stream()
.map(author -> author.getAge())
.reduce((result, element) -> result > element ? element : result);
authorsOptional.ifPresent(age -> System.out.println(age));
}
}
1、惰性求值(如果没有终结操作,没有中间操作时不会得到执行的)
2、流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用)
3、不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下,不会影响原来集合中的元素的。这往往也是我们期待的)
以下是非正常操作(会影响原数据)
authors.stream()
.map(author -> {
author.setAge(author.getAge() + 10);
return author;
})
.forEach(list -> System.out.println(list));
System.out.println(authors);