目的:用于简化集合和数组操作的API。
需求:按照下面的要求完成集合的创建和遍历
创建一个集合,存储多个字符串元素
package com;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class StreamTest {
public static void main(String[] args) {
List<String> names=new ArrayList<>();
Collections.addAll(names,"张三丰","赵敏","张无忌","周芷若","张强");
System.out.println(names);
/* //1、从集合中找出姓张的放到新集合
List<String> zhanglist=new ArrayList<>();
for (String name:names) {
if (name.startsWith("张")){
zhanglist.add(name );
}
}
System.out.println(zhanglist);
//2、找名称长度是3的姓名
List<String> zhangthreelist=new ArrayList<>();
for (String name:zhangthreelist) {
if (name.length()==3){
zhangthreelist.add(name );
}
}
System.out.println(zhangthreelist);*/
//3、使用Stream实现的
names.stream().filter(s->s.startsWith("张")).filter(s -> s.length()==3).forEach(s-> System.out.println(s));
}
}
Stream流的三类方法:
- 集合获取stream流的方式
可以使用Collection接口中的默认方法stream()生成流
名称 说明 |
default Stream<E> stream() 获取当前集合对象的Stream流 |
- 数组获取stream流的方式
名称 说明 |
public static <T> Stream<T> stream(T[] array) 获取当前数组的Stream流 |
public static<T> Stream<T> of(T... values) 获取当前数组/可变数据的stream流 |
package com;
import java.util.*;
import java.util.stream.Stream;
public class stream01 {
public static void main(String[] args) {
//- -----Collection集合获取流------
Collection<String> list=new ArrayList<>();
Stream<String> s=list.stream();
//-------------Hap集合获取流---------
Map<String,Integer> maps=new HashMap<>();
//键流
Stream<String> keystream=maps.keySet().stream();
//值流
Stream<Integer> valuestream=maps.values().stream();
//键值对流
Stream<Map.Entry<String,Integer>> ketandvaluestream=maps.entrySet().stream();
//------数组获取流----------
String[] names={"赵敏","小昭","灭绝"};
Stream<String> namestream=Arrays.stream(names);
Stream<String> namestream2=Stream.of(names);
}
}
常用API:
名称 说明 |
stream<T> filter(Predicate<? super T> predicate) 用于对流中的数据进行过 |
stream<T> limit( long maxSize) 获取前几个元素 |
stream<T> skip(long n) 跳过前几个元素 |
Stream<T> distinct() 去除流中重复的元素。依赖(hashCode和equals方法) |
static <T> Stream<T> concat(Stream a,stream b) 合并a和b两个流为一个流 |
package com.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class stream01 {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("张三丰");
list.add("周芷若");
list.add("赵敏");
list.add("张无忌");
list.add("张强");
//stream<T> filter(Predicate<? super T> predicate)
//法一
/*list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
});*/
//法二
list.stream().filter(s-> s.startsWith("张")).forEach(s-> System.out.println(s));
//stream<T> limit( long maxSize)
long size=list.stream().filter(s ->s.length()==3).count();
System.out.println(size);
list.stream().filter(s->s.startsWith("张")).limit(2).forEach(s-> System.out.println(s));//两个一样
list.stream().filter(s->s.startsWith("张")).limit(2).forEach( System.out::println);
//stream<T> skip(long n)
list.stream().filter(s->s.startsWith("张")).skip(2).forEach( System.out::println);
//Stream<T> distinct()
//给集合前面加上黑马的
//map加工方法:第一个参数原材料->第二个参数是加工后的结果。
list.stream().map(s->"黑马的"+s).forEach(a-> System.out.println(a));
/*list.stream().map(new Function<String, String>() {
@Override
public String apply(String s) {
return "黑马的"+s;
}
});*/
//需求:把所有名称做成学生类
list.stream().map(s->new student(s)).forEach(s-> System.out.println(s));
list.stream().map(student::new).forEach(System.out::println);//构造器引用 方法引用
//合并流
Stream<String> s1=list.stream().filter(s->s.startsWith("张"));
Stream<String> s2=Stream.of("java01","java02");
// static <T> Stream<T> concat(Stream a,stream b) 同一类型用同一类型 不同类型用object(等号前面)
Stream<String> s3=Stream.concat(s1,s2);
s3.forEach(s-> System.out.println(s));
}
}
package com.stream;
public class student {
private String name;
public student() {
}
public student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
'}';
}
}
注意:中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程。
在Stream流中无法直接修改集合、数组中的数据。
Stream流的常见终结操作方法:
名称 说明 |
void forEach(Consumer action) 对此流的每个元素执行遍历操作 |
long count() 返回此流中的元素数 |
案例:
需求:某个公司的开发部门,分为开发一部和二部,现在需要进行年中数据结算。
分析:
- 员工信息至少包含了(名称、性别、工资、奖金、处罚记录)
- 开发一部有4个员工、开发二部有5名员工
- 分别筛选出2个部门的最高工资的员工信息,封装成优秀员工对象Topperformer
- 要求去掉最高和最低工资。分别统计出2个部门的平均月收入,
package com.stream; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; public class stream02 { public static double allmoney1=0; public static double allmoney2=0; public static void main(String[] args) { List<Employee> one=new ArrayList<>(); one.add(new Employee("猪八戒",'男',300000,25000,null)); one.add(new Employee("孙悟空",'男',25000,100,"顶撞上司")); one.add(new Employee("沙僧",'男',20000,20000,null)); one.add(new Employee("小白龙",'男',25000,26000,null)); List<Employee> two=new ArrayList<>(); one.add(new Employee("武松",'男', 1500 , 9000, null)); one.add(new Employee("李逵",'男',200 , 10000, null)); one.add(new Employee("西门庆",'男',500, 100080,"被打")); one.add(new Employee("潘金莲",'女', 350,1000,"被打")); one.add(new Employee("武大郎",'女', 200,0,"下毒")); //1、开发一部的最高工资的员工 //制定大小规则 /*Employee e=one.stream().max((e1,e2)->Double.compare(e1.getSalary()+e1.getBonus() ,e2.getSalary()+e2.getBonus())) .get(); System.out.println(e);*/ Topperformer t=one.stream().max((e1,e2)->Double.compare(e1.getSalary()+e1.getBonus() ,e2.getSalary()+e2.getBonus())) .map(e ->new Topperformer(e.getName(), e.getSalary()+e.getBonus())).get(); System.out.println(t); //2. one.stream().sorted((e1,e2)->Double.compare(e1.getSalary()+e1.getBonus() ,e2.getSalary()+e2.getBonus())) .skip(1).limit(one.size()-2).forEach(e->{ allmoney1+=(e.getSalary()+e.getBonus()); }); System.out.println("开发一部的平均工资:"+allmoney1/(one.size()-2)); //合并两个集合流 Stream<Employee> s1=one.stream(); Stream<Employee> s2=one.stream(); Stream<Employee> s3=Stream.concat(s1,s2); s3.sorted((e1,e2)->Double.compare(e1.getSalary()+e1.getBonus() ,e2.getSalary()+e2.getBonus())) .skip(1).limit(one.size()-2).forEach(e->{ allmoney2+=(e.getSalary()+e.getBonus()); }); //BIGEecimol BigDecimal a=BigDecimal.valueOf(allmoney2); BigDecimal b=BigDecimal.valueOf(one.size()+two.size()-2); System.out.println("开发部的平均工资:"+a.divide(b,2, RoundingMode.HALF_UP)); } } package com.stream; public class Topperformer { private String name; private double mongey; public Topperformer() { } public Topperformer(String name, double mongey) { this.name = name; this.mongey = mongey; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMongey() { return mongey; } public void setMongey(double mongey) { this.mongey = mongey; } @Override public String toString() { return "Topperformer{" + "name='" + name + '\'' + ", mongey=" + mongey + '}'; } } package com.stream; public class Employee { private String name ; private char sex; private double salary; private double bonus; private String punish; //处罚信思 public Employee() { } public Employee(String name, char sex, double salary, double bonus, String punish) { this.name = name; this.sex = sex; this.salary = salary; this.bonus = bonus; this.punish = punish; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } public String getPunish() { return punish; } public void setPunish(String punish) { this.punish = punish; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", sex=" + sex + ", salary=" + salary + ", bonus=" + bonus + ", punish='" + punish + '\'' + '}'; } }
Stream流的收集操作:
收集Stream流的含义︰就是把Stream流操作后的结果数据转回到集合或者数组中去。
Stream流:方便操作集合/数组的手段。
名称 说明
Rcollect(collector collector) 开始收集Stream流,指定收集器
collectors工具类提供了具体的收集方式
-
package com.stream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.function.IntFunction; import java.util.stream.Collectors; import java.util.stream.Stream; public class stream03 { public static void main(String[] args) { List<String> list=new ArrayList<>(); list.add("张三丰"); list.add("周芷若"); list.add("赵敏"); list.add("张无忌"); list.add("张强"); list.add("张三丰"); Stream<String> s1=list.stream().filter(s->s.startsWith("张")); List<String> zhanglist= s1.collect(Collectors.toList()); System.out.println(zhanglist); //流只能使用一次 Stream<String> s2=list.stream().filter(s->s.startsWith("张")); Set<String> zhangset= s2.collect(Collectors.toSet()); System.out.println(zhangset); //set会去掉重复 Stream<String> s3=list.stream().filter(s->s.startsWith("张")); //Object[] arrs=s3.toArray(); String[] arrs=s3.toArray(String[]::new); System.out.println("Array数组内容:"+ Arrays.toString(arrs)); } }
名称 说明
public static <T> collector toList() 把元素收集到List集合中
public static <T> collector toset() 把元素收集到Set集合中
public static collector toMap(Function keyMapper , Function valueMapper)
把元素收集到Map集合中