Java8 Stream基础API
使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询,Stream API提供了一种高效且易于使用的处理数据的方式。
1、Stream是什么?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。集合讲的是数据,Stream讲的是计算。
“注意”
(1) Stream自己不会存储元素。
(2) Stream不会改变源对象。相反,它会返回一个持有结果的新Stream。
(3) Stream操作是延迟执行的,这意味着它会等到需要结果时才执行。
2、Stream操作步骤
(1)创建Stream
一个数据源(如:集合,数组),获取一个流
(2)中间操作
一个中间操作链,对数据源的数据进行处理。例:过滤,映射等
(4)终止操作
一旦执行终止操作,就执行中间操作链,并产生结果,之后,不再被使用。
3、stream实例化4种方式
package stream;
import bean.Person;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class TestDay1 {
//创建stream方式一:通过集合
@Test
public void test1(){
List<Person> list = Person.getPersonList();
//default Stream<E> stream():返回一个顺序流
Stream<Person> stream = list.stream();
//default Stream<E> parallelStream() 返回一个并行流
Stream<Person> parallelStream = list.parallelStream();
}
//创建stream方式二:通过数组
@Test
public void test2(){
int[] arr = new int[]{1,2,3};
IntStream intStream = Arrays.stream(arr);
//对象数组返回对象类型stream
Person p1 = new Person("jim",11);
Person p2 = new Person("angel",12);
Person[] arr2 = new Person[]{p1,p2};
Stream<Person> parallelStream = Arrays.stream(arr2);
}
//创建stream方式三:通过stream的of()方法
@Test
public void test3(){
Stream<Integer> stream = Stream.of(1,2,3,4,5);
}
//创建stream方式四:创建无限流,造数据用,一般不用
@Test
public void test4(){
//迭代
// public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
//遍历输出前十个偶数 limit中间操作,forEach 终止操作
Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
//生成
//public static<T> Stream<T> generate(Supplier<T> s)
Stream.generate(Math::random).limit(10).forEach(System.out::println);
}
}
4、Stream的中间操作
(1)筛选与切片(filter,limit,skip,distinct)
(2)映射 (map)
(3)排序(sored)
(4) 并行流(parallel),节约时间
package stream;
import bean.Person;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class TestMid {
//stream的中间操作一、筛选与切片
@Test
public void test1(){
List<Person> list = Person.getPersonList();
//default Stream<E> stream():返回一个顺序流
Stream<Person> stream = list.stream();
//集合中年龄大于12岁的
stream.filter(p->p.getAge()>12).forEach(System.out::println);
System.out.println("#######################");
//limit(n)截断流,不超过给定长度n
list.stream().limit(3).forEach(System.out::println);
System.out.println("#######################");
//skip(n)跳出元素,跳过前n个,若集合中不足,返回空流 与limit互补
list.stream().skip(13).forEach(System.out::println);
System.out.println("#######################");
//distinct()--筛选,通过流所生成元素的hashCode()和equals去除重复元素
list.add(new Person("Tom",22));
list.add(new Person("Tom",22));
list.add(new Person("Tom",23));
list.stream().distinct().forEach(System.out::println);
}
//stream的中间操作二、映射
@Test
public void test2(){
List<String> list = Arrays.asList("aaa","bbb","ccc");
//map(Function f)接收一个函数作为参数,将元素转换成其他形式或者提取信息,
// 该函数会被应用到每个元素上,并将其映射成一个新元素
list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
System.out.println("#######################");
//练习
List<Person> personList = Person.getPersonList();
Stream<String> stringStream = personList.stream().map(Person::getName);
stringStream.filter(name->name.length()>3).forEach(System.out::println);
//flatMap(Function f)将流中的每个值都换成另外一个流,然后把所有的流连接成一个流
//1.用map相当于list1.add(list2);
Stream<Stream<Character>> streamStream = list.stream().map(TestMid::StringToStream);
streamStream.forEach(s->{
s.forEach(System.out::println);
});
System.out.println("#######################");
//2.用flatMap当于list1.addAll(list2)
Stream<Character> characterStream = list.stream().flatMap(TestMid::StringToStream);
characterStream.forEach(System.out::println);
}
//将字符串中的多个字符构成的集合转化为对应的stream的实例
public static Stream<Character> StringToStream(String str){
ArrayList<Character> arrayList = new ArrayList<>();
for(Character c:str.toCharArray()){
arrayList.add(c);
}
return arrayList.stream();
}
//简单举例类比
@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);
list2.add(6);
//输出4个元素
// list1.add(list2);
//System.out.println(list1);
//输出6个元素
list1.addAll(list2);
System.out.println(list1);
}
//stream的中间操作三、排序
@Test
public void test4() {
//1、sored()自然排序
List<Integer> list = Arrays.asList(5, 1, -1, 23, 3, 20);
list.stream().sorted().forEach(System.out::println);
System.out.println("#######################");
//2、sored(comparator com)定制排序
List<Person> list1 = Person.getPersonList();
list1.stream().sorted((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge())).
forEach(System.out::println);
}
}
5、Stream的终止操作
(1)匹配与查找(forEach,min,max,count)
(2)规约 (reduce)
(3)收集collect(Collectors c) 将流转化为其他形式,
接收一个Collectors接口实现,用于给Stream中元素做汇总的方法。例如:(set,List)
package stream;
import bean.Person;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OverTest {
//1、匹配与查找
@Test
public void test1(){
//(1)allMatch(Predicate p)检查是否匹配所有元素
List<Person> p1 = Person.getPersonList();
boolean b1 = p1.stream().allMatch(p -> p.getAge() > 10);
System.out.println(b1);
System.out.println("#######################");
//(2)anyMatch(Predicate p)检查是否匹配任一元素
List<Person> p2 = Person.getPersonList();
boolean b2 = p2.stream().anyMatch(p -> p.getAge() > 20);
System.out.println(b2);
System.out.println("#######################");
//(3)findFirst返回第一个元素
List<Person> p3 = Person.getPersonList();
Optional<Person> first = p3.stream().findFirst();
System.out.println(first);
System.out.println("#######################");
//(4)count()返回流中元素的总个数
List<Person> p4 = Person.getPersonList();
long count = p4.stream().filter(p -> p.getAge() > 12).count();
System.out.println(count);
System.out.println("#######################");
//(5)max(Comparator c)返回流中的最大值
List<Person> p5= Person.getPersonList();
Stream<Integer> stream = p5.stream().map(p -> p.getAge());
Optional<Integer> max = stream.max(Integer::compareTo);
System.out.println(max);
System.out.println("#######################");
//(6)min(Comparator c)返回流中的最小值
List<Person> p6= Person.getPersonList();
Optional<Person> min = p6.stream().min((a, b) -> Integer.compare(a.getAge(), b.getAge()));
System.out.println(min);
System.out.println("#######################");
//(7)forEach(Consumer c)内部迭代器
List<Person> p7= Person.getPersonList();
p7.stream().forEach(System.out::println);
System.out.println("#######################");
//集合里面的遍历操作
p7.forEach(System.out::println);
}
//2、规约
@Test
public void test2() {
//(1)reduce(T identity, BinaryOperator<T> accumulator)可以将流中元素反复结合起来,得到一个值返回
//求和1-5
List<Integer> list = Arrays.asList(1,2,3,4,5);
Integer reduce = list.stream().reduce(0, Integer::sum); //第一个参数为初始值
System.out.println(reduce);
System.out.println("#######################");
//2.Optional<T> reduce(BinaryOperator<T> accumulator)求和,返回Optional<T>
//求和年龄
List<Person> p1 = Person.getPersonList();
// Optional<Integer> reduce1 = p1.stream().map(Person::getAge).reduce(Integer::sum);
Optional<Integer> reduce1 = p1.stream().map(Person::getAge).reduce((a,b)->a+b);
System.out.println(reduce1);
System.out.println("#######################");
}
//3、收集collect(Collectors c) 将流转化为其他形式,
// 接收一个Collectors接口实现,用于给Stream中元素做汇总的方法 例如:(set,List)
@Test
public void test3() {
//1.输出List
List<Person> p1 = Person.getPersonList();
List<Person> personList = p1.stream().filter(a -> a.getAge() > 20).collect(Collectors.toList());
personList.forEach(System.out::println);
System.out.println("#######################");
//2.输出set
Set<Person> personSet = p1.stream().filter(a -> a.getAge() > 20).collect(Collectors.toSet());
personSet.forEach(System.out::println);
System.out.println("#######################");
}
}
用到的Person类
package bean;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public Person() {
System.out.println("Person()......");
}
public Person(Integer age) {
this.age = age;
System.out.println("Person(Integer age)......"+age);
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) &&
Objects.equals(age, person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public static List<Person> getPersonList(){
List<Person> personList = new ArrayList<>();
personList.add(new Person("张三力",12));
personList.add(new Person("李四狗",11));
personList.add(new Person("王五蛋",13));
personList.add(new Person("Tom",22));
personList.add(new Person("Jerry",21));
personList.add(new Person("Mary",23));
return personList;
}
}
Stream简单基础和实现到此结束,具体详细方法和操作可查看相关API添加链接描述。