Java8 Stream流
作者:互联网
Stream流
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
1 起始操作
在 Java 8 中, 集合接口有两个方法来生成流:
- stream() − 为集合创建串行流。
- parallelStream() − 为集合创建并行流。
生成流
// 为集合创建串行流
Stream<String> stream = list.stream();
// 为集合创建并行流
Stream<String> stream = list.parallelStream();
2 中间操作
过滤器
public class Demo01 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素。
List<String> list = new ArrayList<>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
/*
filter()方法是中间操作,中间操作都用lambda表达式。
*/
//需求1:把list集合中以“张”开头的元素在控制台输出。
System.out.println("======需求1=====");
list.stream().filter(x -> x.startsWith("张")).forEach(System.out::println);
//需求2:把list集合中长度为3的元素在控制台输出。
System.out.println("======需求2=====");
list.stream().filter(x -> x.length() == 3).forEach(System.out::println);
//需求3:把list集合中以“张”开头的,长度为3的元素在控制台输出。
System.out.println("======需求3=====");
//在一个过滤器中要满足两个条件。
list.stream().filter(x -> x.startsWith("张") && x.length() == 3).forEach(System.out::println);
System.out.println("-----");
//用两个过滤器,先过滤出以“张”开头的元素,再过滤出长度为3的元素。
list.stream().filter(x -> x.startsWith("张")).filter(x -> x.length() == 3).forEach(System.out::println);
}
}
理解stream流的时候,可以顺便复习复习lambda表达式。
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
限制、跳过
/*
中间操作
限制:limit()
跳过:skip()
*/
public class Demo02 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素。
List<String> list = new ArrayList<>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:取前3个数据在控制台输出。
System.out.println("======需求1======");
list.stream().limit(3).forEach(System.out::println);
//需求2:跳过3个元素,把剩下的元素在控制台输出。
System.out.println("=====需求2=======");
list.stream().skip(3).forEach(System.out::println);
//需求3:跳过2个元素,把剩下的元素中前2个在控制台输出。
System.out.println("=====需求3======");
//先用一个skip(2)跳过前两个元素,在剩下的元素中用limit(2)取前两个元素并输出。
list.stream().skip(2).limit(2).forEach(System.out::println);
}
}
合并流、去重
/*
中间操作
合并流:concat()------这是一个静态方法。Stream.concat()
去重:distinct()
*/
public class Demo03 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素。
List<String> list = new ArrayList<>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:取前4个数据组成一个流。
Stream<String> stream1 = list.stream().limit(4);
//需求2:跳过2个数据组成一个流。
Stream<String> stream2 = list.stream().skip(2);
//需求3:合并需求1和需求2得到的流,并把结果在控制台输出。
//合并流的方法concat()是一个静态方法。
Stream.concat(stream1, stream2).forEach(System.out::println);
//需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复。
Stream.concat(stream1, stream2).distinct().forEach(System.out::println);
}
}
排序
/*
中间操作
自然排序:sorted()
用比较器比较排序:sorted(Comparator comparator)
*/
public class Demo04 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素。
List<String> list = new ArrayList<>();
list.add("linqingxia");
list.add("zhangmanyu");
list.add("wangzuxian");
list.add("liuyan");
list.add("zhangming");
list.add("zhangwuji");
//需求1:按照字母顺序把数据在控制台输出。
System.out.println("====需求1====");
list.stream().sorted().forEach(System.out::println);
//需求2:按照字符串长度把数据在控制台输出。
System.out.println("====需求2====");
//前面-后面:从小到大 后面-前面:从大到小
list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println);
//需求3:先按照长度,再按照字母顺序排序。
System.out.println("====需求3====");
list.stream().sorted((s1, s2) -> {
int sort1 = s1.length() - s2.length();
int sort2 = sort1 == 0 ? s1.compareTo(s2) : sort1;
return sort2;
}).forEach(System.out::println);
}
}
返回此流元素组成的流
/*
中间操作
返回此流元素组成的流:map()
IntSteam mapToInt() 返回一个IntSteam类型的结果
*/
public class Demo05 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
//需求:将集合中的字符串数据转换为整数之后在控制台输出。
System.out.println("====需求1====");
list.stream().map(x->Integer.parseInt(x)).forEach(System.out::println);
//以上方法可以改进。
System.out.println("====需求1改进====");
list.stream().map(Integer::parseInt).forEach(System.out::println);
//以上方法还可以改进。
System.out.println("====需求1再改进====");
//用第3个
list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//求和
int sum = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println("求和:" + sum);
}
}
3 终结操作
输出
/*
终结操作
输出:forEach()
返回流中的元素数:count()
*/
public class Demo06 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素。
List<String> list = new ArrayList<>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:把集合中的元素在控制台输出。
System.out.println("====需求1====");
list.stream().forEach(System.out::println);
//需求2:统计集合中有几个以“张”开头的元素,并把统计结果在控制台输出。
System.out.println("====需求2====");
long count = list.stream().filter(x -> x.startsWith("张")).count();
System.out.println(count);
}
}
收集操作
map只是把一个新的流转换为一个新的流,而collect的把流转换为集合。
/*
Stream流的收集操作
*/
public class Demo08 {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
//需求1:得到名字为3个字的流
Stream<String> stream = list.stream().filter(x -> x.length() == 3);
//需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历。
List<String> collectList = stream.collect(Collectors.toList());
System.out.println("=====List=====");
for (String string : collectList) {
System.out.println(string);
}
//创建Set集合对象。
Set<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(30);
set.add(40);
//需求3:得到大于25的流
Stream<Integer> integerStream = set.stream().filter(x -> x > 25);
//需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历。
Set<Integer> collectSet = integerStream.collect(Collectors.toSet());
System.out.println("=====Set=====");
//Set集合是无序的,输出无序。
for (Integer integer : collectSet) {
System.out.println(integer);
}
//定义一个字符串数组。
String string[] = {"林青霞,1", "张曼玉,2", "王祖贤,3", "柳岩,4"};
//需求5:得到字符串中数据大于2的流。
Stream<String> stringStream = Stream.of(string).filter(x -> Integer.parseInt(x.split(",")[1]) > 2);
//需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,序号作值。
Map<String, Integer> integerMap = stringStream.collect(Collectors.toMap(x -> x.split(",")[0], x -> Integer.parseInt(x.split(",")[1])));
Set<String> ketSet = integerMap.keySet();
System.out.println("=====Map=====");
for (String str : ketSet) {
Integer value = integerMap.get(str);
System.out.println(str + "=" + value);
}
}
}
4 练习
/*
Stream流的练习
现在有两个 ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
1.男演员只要名字为3个字的前三人
2.女演员只要姓林的,井且不要第一个
3.把过滤后的男演员姓名和女演员姓名合并到一起
4.把上一步操作后的元素作为构造方法的参数创建演员对象遍历数据
演员类Actor已经提供,里面有一个成员变量,一个带参造方法,以及成员变量对应的 get/set方法
*/
public class Demo01 {
public static void main(String[] args) {
//男演员集合
List<String> manList = new ArrayList<>();
manList.add("周润发");
manList.add("成龙");
manList.add("刘德华");
manList.add("吴京");
manList.add("周星驰");
manList.add("李连杰");
//女演员集合
List<String> womanList = new ArrayList<>();
womanList.add("林心如");
womanList.add("张曼玉");
womanList.add("林青霞");
womanList.add("柳岩");
womanList.add("林志玲");
womanList.add("王祖贤");
System.out.println("================方法1================");
Stream<String> manListStream = manList.stream().filter(name -> name.length() == 3).limit(3);
Stream<String> womanListStream = womanList.stream().filter(name -> name.startsWith("林")).skip(1);
Stream<String> concatStream = Stream.concat(manListStream, womanListStream);
concatStream.map(name -> new Actor(name)).forEach(System.out::println);
// concatStream.map(Actor::new).forEach(System.out::println);
System.out.println("================方法2================");
Stream.concat(manList.stream().filter(x -> x.length() == 3).limit(3)
, womanList.stream().filter(x -> x.startsWith("林")).skip(1))
.map(Actor::new)
.forEach(System.out::println);
}
}
class Actor {
private String name;
public Actor() {
}
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
'}';
}
}
参考资料:Java 8 Stream | 菜鸟教程 (runoob.com)
标签:stream,Stream,list,System,add,println,Java8,out 来源: https://www.cnblogs.com/Kled/p/16561888.html