什么是stream? 也叫Stream流,是JDK8开始新增的一套API(java.util.stream.*)可以用于操作集合或者数组的数据。
优势:
Stream流大量结合了Lamdba表达式的语法风格来编程,提供了一套更加强大的,更加简单的方式操作集合或数组中的数据, 代码更加简洁,可读性更好。
初体验Stream流: 需求:在一组list集合中把所有以张开头,且是3个字的元素存储到一个新的集合中
我们先不使用Stream流演示一下:
java
public static void main(String[] args) {
List<String> names = new ArrayList<>();
Collections.addAll(names,"无极","单独","范德萨","VS是否","孙子","孙尚香","孙纷纷");
System.out.println(names);
// 找出姓张,存入到一个信息的集合中
ArrayList<String> list = new ArrayList<>();
for (String name : names) {
if (name.startsWith("孙") && name.length() == 3){
list.add(name);
}
}
System.out.println(list);
}
/** [无极, 单独, 范德萨, VS是否, 孙子, 孙尚香, 孙纷纷]
- [孙尚香, 孙纷纷]
*/
下面我们使用Stream流来完成这个需求:
java
public class StreamDemo1 {
public static void main(String[] args) {
List <String> nameList = names.stream().filter(s -> s.startsWith("孙"))
.filter(a -> a.length() == 3).collect(Collectors.toList());
System.out.println(nameList);
}
// [孙尚香, 孙纷纷]
}
Stream流的使用步骤:
获取Stream流: 获取集合的Stream流:
获取list集合的stream流:
java
public static void main(String[] args) {
// 1 如何获取list集合的stream流
ArrayList<String> names = new ArrayList<>();
Collections.addAll(names,"无极","单独","范德萨","VS是否","孙子","孙尚香","孙方法");
Stream<String> stream = names.stream();
}
如何获取set集合的stream流:
java
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流:
java
Map<String,Double> map = new HashMap<>();
map.put("迪丽热巴",171.4);
map.put("古力娜扎",168.9);
map.put("马尔科是",177.8);
map.put("卡尔",173.4);
Set<String> keys = map.keySet();
Stream<String> kStream = keys.stream();
Collection<Double> values = map.values();
Stream<Double> allValues = values.stream();
//第二种方式: 示例:获取map集合中键值包含巴的人的信息
Set<Map.Entry<String, Double>> entries = map.entrySet();
Stream<Map.Entry<String, Double>> kvs = entries.stream();
kvs.filter(s -> s.getKey().contains("巴")).
forEach(e -> System.out.println(e.getKey() + "--->" + e.getValue()));
//迪丽热巴--->171.4
获取数组的Stream流:
java
String[] names2 = {"孙尚香","孙凤的","大山","多少"};
Stream<String> streamName1 = Arrays.stream(names2);
Stream<String> streamName2 = Stream.of(names2);
streamName1.forEach(s -> System.out.print(s+" "));
// 孙尚香 孙凤的 大山 多少
Stream流常见的中间方法: 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)
filter的使用:
需求:过滤姓名以张开头,并且名字长度等于3的名字
java
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若","赵敏","张强","张三丰");
// 1、过滤方法 //过滤姓名以张开头,并且名字长度等于3的名字
list.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(e -> System.out.println(e));
//张无忌
//张三丰
socred 排序
先准备一个 Movie类和Actor类:
Movies类:
java
public class Movie implements Comparable<Movie>{
private String name;
private Double score;
private String actor;
public Movie() {
}
public Movie(String name, Double score, String actor) {
this.name = name;
this.score = score;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Movie movie = (Movie) o;
return Objects.equals(name, movie.name) && Objects.equals(score, movie.score) && Objects.equals(actor, movie.actor);
}
@Override
public int hashCode() {
return Objects.hash(name, score, actor);
}
@Override
public String toString() {
return "Movie{" +
"name='" + name + '\'' +
", score=" + score +
", actor='" + actor + '\'' +
'}';
}
@Override
public int compareTo(Movie o) {
return Double.compare(this.score,o.score);
}
}
Actor类:
java
public class Actor {
private String name;
private Double actor;
public Actor() {
}
public Actor(String name, Double actor) {
this.name = name;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getActor() {
return actor;
}
public void setActor(Double actor) {
this.actor = actor;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
", actor=" + actor +
'}';
}
}
准备一个集合,排序。
java
List<Movie> movies = new ArrayList<>();
movies.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
movies.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
// 集合中如果存储对象,
// 方式一:对象类可以实现Comparable接口,指定比较规则 // sorted方法就可以按照规则进行排序,否则报错!
movies.stream().sorted().forEach(e -> System.out.println(e));
// 方式二:自带比较器
movies.stream().sorted((o1,o2) -> Double.compare(o2.getScore(),o1.getScore()));
/**
* Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
*/
limit 截取:
需求:截取前两个
java
movies.stream().sorted().limit(3).forEach(System.out::println);
/**
* Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
*/
skip 跳过:
需求:跳过前两个
java
movies.stream().skip(2).forEach(e -> System.out.println(e));
/**
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
*/
distinct 去重:
java
movies.stream().distinct().forEach(e -> System.out.println(e));
/**
* Movie{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
*/
map加工方法(映射): 需求:把流上的数据加工成新数据。
java
movies.stream().sorted((Movie o1, Movie o2) -> Double.compare(o2.getScore(),o1.getScore()))
.map(m -> new Actor(m.getName(),m.getScore())).forEach(e -> System.out.println(e));
/**
* Actor{name='摔跤吧,爸爸', actor=9.5}
* Actor{name='三傻宝莱坞', actor=8.5}
* Actor{name='三傻宝莱坞', actor=8.5}
* Actor{name='阿甘正传', actor=7.5}
*/
合并流:
需求:把两个流连接起来
java
Stream<String> s1 = Stream.of("张三", "楚留香", "西门吹牛");
Stream<String> s2 = Stream.of("李四", "石观音");
// public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
Stream<String> concat = Stream.concat(s1, s2);
concat.forEach(e -> System.out.println(e));
/**
* 张三
* 楚留香
* 西门吹牛
* 李四
* 石观音
*/
Stream流常见的终结方法: 终结方法指的是调用完成后,不会返回新的Stream了,没法继续使用流了。
forEach:方法
需求:打印出来集合中的数据
java
List<Movie> movies = new ArrayList<>();
movies.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
movies.add(new Movie("三傻宝莱坞", 8.5, "阿米尔汗2"));
movies.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
// 1、forEach
movies.forEach(e -> System.out.println(e));
ini
/**
* {name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='三傻宝莱坞', score=8.5, actor='阿米尔汗2'}
* Movie{name='阿甘正传', score=7.5, actor='汤姆汉克斯'}
*/
count 取数量:
需求:求出集合中的数据的数量
System.out.println(movies.stream().count());
// 4 max 求最大值:
需求:根据评分升序排序
java
Movie max = movies.stream().max((o1,o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
System.out.println(max);
//{name='摔跤吧,爸爸', score=9.5, actor='阿米尔汗'}
min 求最小值:
需求:按照评分排序,找到最小值
scss
Movie min = movies.stream().min((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();
System.out.println(min);
// {name='阿甘正传', score=7.5, actor='汤姆汉克斯'} collect 收集流:
需求:收集Stream流:把流中的数据恢复到集合或者数组中去
java
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.add("张三丰");
// 收集到List集合 //把姓张的学生收集到一个新的集合中
List<String> list2 = list.stream().filter(s -> s.startsWith("张")).collect(Collectors.toList());
System.out.println(list2);
// 收集到Set集合(流只能用一次)
Set<String> set1 = list.stream().filter(s -> s.startsWith("张") && s.length() == 3).collect(Collectors.toSet());
System.out.println(set1);
//[张无忌, 张强, 张三丰, 张三丰]
[张三丰, 张无忌]
//
收集到数组中:
java
Stream<String> arr = list.stream().filter(s -> s.startsWith("张"));
Object[] array = arr.toArray();
System.out.println(Arrays.toString(array));
// [张无忌, 张强, 张三丰, 张三丰]
// 拓展 收集到Map集合。Movice需要重写 equals 和 hashCode 方法
List<Movie> movies1 = new ArrayList<>();
movies1.add(new Movie("摔跤吧,爸爸", 9.5, "阿米尔汗"));
movies1.add(new Movie("三傻宝莱坞", 18.5, "阿米尔汗2"));
movies1.add(new Movie("三傻宝莱坞", 18.5, "阿米尔汗2"));
movies1.add(new Movie("阿甘正传", 7.5, "汤姆汉克斯"));
Map<String, Double> collect = movies1.stream()
.distinct().collect(Collectors.toMap(movie -> movie.getName(), movie -> movie.getScore()));
System.out.println(collect);
// {摔跤吧,爸爸=9.5, 阿甘正传=7.5, 三傻宝莱坞=18.5}