jdk1.8新特性之StreamAPI
StreamAPI可以用来干什么?
Collection是用来在内存中存储数据,而StreamAPI则可以在CPU层面上进行计算
怎么使用StreamAPI?
使用细节:①不会存储值②不会改变源数据,返回一个新的stream③延时操作,只有当写了终止操作才会执行
主要从两个方面:①如何实例化②如何使用方法
1.Collection中的stream()方法
2.Arrays中的stream()方法
3.Stream中的of()方法
4.Stream中的iterate()和generate()方法
class Employee1{
private int id;
private String name;
private int age;
private double salary;
public Employee1() {
super();
}
public Employee1(int id, String name, int age, double salary) {
super();
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
@Override
public int hashCode() {
return Objects.hash(age, id, name, salary);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee1 other = (Employee1) obj;
return age == other.age && id == other.id && Objects.equals(name, other.name)
&& Double.doubleToLongBits(salary) == Double.doubleToLongBits(other.salary);
}
public static List<Employee1> getList(){
List<Employee1> list=new ArrayList<>();
list.add(new Employee1(1001,"王石",55,4999.9));
list.add(new Employee1(1002,"马化腾",49,8888.8));
list.add(new Employee1(1003,"马云",46,6666.6));
list.add(new Employee1(1004,"扎克伯格",38,9999.9));
list.add(new Employee1(1005,"雷军",22,3999.9));
list.add(new Employee1(1005,"雷军",22,3999.9));
return list;
}
}
@Test
public void test1() {
// 方式1:调用Collection的Stream()方法
List<Employee1> list=Employee1.getList();
Stream<Employee1> s1=list.stream(); //调用的是顺序流,按照添加的顺序
Stream<Employee1> reverseStream=list.parallelStream(); //逆序流
//方式2:调用Arrays中的stream()方法
int [] arr=new int [] {1,2,3,4};
IntStream s2=Arrays.stream(arr);
//方式3:使用Stream中的of方法
Stream s=Stream.of(1,2,3,4);
//方式4:了解
// 迭代器
Stream<Integer> s3=Stream.iterate(0, t->t+2).limit(10);
//生成器
Stream<Employee1> s4=Stream.generate(Employee1::new).limit(10);
}
Stream的中间操作:
1.过滤和切片 :①filter(过滤)②limit(限制数量)③skip(跳过)④distinct(去重)(底层调用hashCode()和equals()方法实现)
@Test
public void test2() {
List<Employee1> list=Employee1.getList();
// 1.filter
list.stream().filter(e->e.getSalary()>5000).forEach(System.out::println); //筛选出薪资高于5000的员工
System.out.println("***************");
// 2.limit
list.stream().limit(2).forEach(System.out::println); // 切片,切出前两个员工
System.out.println("***************");
// 3.skip
list.stream().skip(2).forEach(System.out::println); //切片,跳过前两个员工
System.out.println("***************");
// 4.distinct
list.stream().distinct().forEach(System.out::println); // 去重
}
2.map和flatmap之间的区别类似于add和addAll之间的区别
@Test
public void test3() {
List list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
List list2=new ArrayList<>();
list2.add(4);
list2.add(5);
list1.add(list2);
System.out.println(list1);
list1.remove(list2);
list1.addAll(list2);
System.out.println(list1);
}
@Test
public void test4() {
List<Employee1> list=Employee1.getList();
// map
list.stream().map(e->e.getSalary()).forEach(System.out::println);
System.out.println("**************");
// flatmap
Stream<List<Integer>> s= Stream.of(Arrays.asList(1),Arrays.asList(2,3),Arrays.asList(4,5,6));
s.flatMap(child->child.stream()).forEach(System.out::println);
}
3.sorted():自然排序和sorted(Comparator com):定制排序
@Test
public void test5() {
//sorted
List<Employee1> list=Employee1.getList();
list.stream().sorted((e1,e2)->{
int num=Double.compare(e1.getSalary(), e2.getSalary());
if(num!=0) {
return num;
}else {
int age=Integer.compare(e1.getAge(), e2.getAge());
if(age!=0) {
return age;
}else {
return e1.getName().compareTo(e2.getName());
}
}
}).forEach(System.out::println);
}
终止操作
1.匹配和查找
@Test
public void test6() {
// 终止操作
// allmatch:是否全匹配 anymatch:是否有一个匹配 nonmatch:是否都不匹配
List<Employee1> list=Employee1.getList();
boolean b1=list.stream().allMatch(e->e.getSalary()>10000);
System.out.println(b1); //false
boolean b2=list.stream().anyMatch(e->e.getName().contains("军"));
System.out.println(b2); //true
boolean b3=list.stream().noneMatch(e->e.getAge()<12);
System.out.println(b3); //true
// findFirst:返回第一个 findany:返回任意一个
Optional<Employee1> o1=list.stream().findFirst();
System.out.println(o1);
Optional<Employee1> o2=list.stream().findAny();
System.out.println(o2); // 因为是顺序流所以是第一个
// count:返回个数 max:返回最大 min:返回最小 forEach
long count=list.stream().count();
System.out.println(count);
Optional<Employee1> o3=list.stream().max((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(o3);
Optional<Employee1> o4=list.stream().min((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(o4);
}
2. 规约 reduce
@Test
public void test8() {
// 规约 reduce
List<Employee1> list=Employee1.getList();
Double d=list.stream().map(e->e.getSalary()).reduce(100.0,(t1,t2)->t1+t2); // 底数100
System.out.println(d);
Optional<Double> d1=list.stream().map(e->e.getSalary()).reduce((t1,t2)->t1+t2);
System.out.println(d1);
}
3.收集 collect
@Test
public void test7() {
//收集 collect Collectors.toList:转化为List Collectors.toSet:转化为Set
List<Employee1> list=Employee1.getList();
List<List<Employee1>> l1=list.stream().map(e->{
List<Employee1> l2=new ArrayList<>();
if(e.getSalary()>5000)
l2.add(e);
return l2;
}).collect(Collectors.toList());
List<Employee1> l3=l1.stream().flatMap(child->child.stream()).collect(Collectors.toList());
System.out.println(l3);
Set<Employee1> set=list.stream().collect(Collectors.toSet());
System.out.println(set);
}
Optional类 :作用处理空指针异常
class Girl{
private String name;
public Girl() {
super();
}
public Girl(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Girl [name=" + name + "]";
}
}
class Boy{
private Girl girl;
public Boy() {
super();
}
public Boy(Girl girl) {
super();
this.girl = girl;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
@Override
public String toString() {
return "Boy [girl=" + girl + "]";
}
}
@Test
public void test9() {
// ofNullable(T t) : t可以为空 orElse:有对象使用默认的,否则使用其它的
Boy boy=null;
System.out.println(getGirlName(boy));
boy=new Boy();
System.out.println(getGirlName(boy));
boy=new Boy(new Girl("苍老师"));
System.out.println(getGirlName(boy));
}
public String getGirlName(Boy boy) {
Optional<Boy> b=Optional.ofNullable(boy);
Boy b1=b.orElse(new Boy(new Girl("古力娜扎")));
Girl girl=b1.getGirl();
Optional<Girl> g=Optional.ofNullable(girl);
Girl g1=g.orElse(new Girl("迪丽热巴"));
return g1.getName();
}