文章目录

背景

Java8新增了Stream流的API,允许用户使用lambda表达式,简单的操纵集合等数据结构。

Steram流的思想

  • Stream不会存储数据,是有关算法和计算的,Stream就如同一个高级的流水线,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
  • Stream可以并行化操作,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream的并行操作依赖于Java7中引入的Fork/Join框架(JSR166y)来拆分任务和加速处理过程。
  • Stream的数据源可以是集合、数组等。

深入理解Java Stream流_stream

使用Stream流的例子

当我们使用一个流的时候,通常包括三个基本步骤:

  1. 获取一个数据源 ;
  2. 数据转换 ;
  3. 执行操作获取想要的结果。
  • 使用传统方式与Stream流API两种方式对比:过滤出集合中的偶数并输出。
/**
* 使用Stream流过滤集合中的数据
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamFilterDemo {

public static void main(String[] args) {
// 创建一个集合,存放1到100的整数
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
list.add(i);
}

// 使用传统方式过滤出偶数
for (Integer i : list) {
if (i % 2 == 0) {
System.out.println(i);
}
}

// 使用stream流方式过滤出偶数
Stream<Integer> stream = list.stream();
stream.filter(i -> i % 2 == 0).forEach(i -> System.out.println(i));

// 以下语句错误:Stream流只能使用一次
//stream.filter(i->i%2!=0).forEach(i -> System.out.println(i));
}
}

获取流的两种方式

1、根据Collection获取流
/**
* 通过Collection获取流
*
* @author zhuhuix
* @date 2020-07-26
*/
public class CollectionStream {
public static void main(String[] args) {


// 数组集合转换化Stream流
List<String> list = new ArrayList<>();
Stream<String> stringStream = list.stream();

// 将HashMap中的键值集合分别转化为Stream流
Map<String,String> map = new HashMap<>();
Set<String> keySet = map.keySet();
Stream<String> keyStream = keySet.stream();

Collection<String> values = map.values();
Stream<String> valueStream = values.stream();

}
}
2、根据Stream接口的静态方式of获取流
/**
* 通过Stream.of获取流
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamOf {
public static void main(String[] args) {
//将数组通地Stream.of转换为Stream流
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);

Integer[] array={1,2,3,4,5,6,7};
Stream<Integer> arrayStream = Stream.of(array);
}
}

Stream流的常用方法

1、forEach
  • forEach用来遍历流中的数据,此方法是一个终结方法(调用此方法后不能继续调用Stream流的其他方法)
/**
* Stream流的forEach方法:void forEach(Consumer<? super T> action;
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamForEach {
public static void main(String[] args) {

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
integerStream.forEach(integer -> System.out.println(integer));
}
}
2、filter
  • 通过filter方法将一个流转换成另一个子集流
/**
* Stream流的filter方法:Stream<T> filter(Predicate<? super T> predicate);
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamFilter {
public static void main(String[] args) {
// 通过filter方法过滤出偶数
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
Stream<Integer> newIntegerStream = integerStream.filter(integer -> integer % 2 == 0);
newIntegerStream.forEach(integer -> System.out.println(integer));
}
}
3、map
  • 通过map方法将流中的元素映射到另一个流中,比如元素类型的转换
/**
* Stream流的map方法:<R> Stream<R> map(Function<? super T, ? extends R> mapper);
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamMap {
public static void main(String[] args) {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);

// 将整型元素通过map方法转换成字符串类型
Stream<String> stringStream = integerStream.map(integer -> "字符:"+integer.toString());

stringStream.forEach(s -> System.out.println(s));
}
}
4、count
  • 统计流中元素的个数,该方法是终结方法
/**
* Stream流的count方法: long count();
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamCount {
public static void main(String[] args) {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
long count = integerStream.count();
System.out.println(count);
}
}
5、limit
  • 对流进行截取,获取只包含前N个元素的新流。
/**
* Stream流的limt方法: Stream<T> limit(long maxSize);
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamLimit {
public static void main(String[] args) {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
// 取流中前4个元素
Stream<Integer> newIntegerStream = integerStream.limit(4);
newIntegerStream.forEach(integer -> System.out.println(integer));
}

}
6、skip
  • 使用skip方法跳过前N个元素获取一个截取之后的新流
/**
* Stream流的skip方法: Stream<T> skip(long n);
*
* @author zhuhuix
* @date 2020-07-26
*/
public class SteamSkip {
public static void main(String[] args) {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
// 取流中前4个元素
Stream<Integer> newIntegerStream = integerStream.skip(4);
newIntegerStream.forEach(integer -> System.out.println(integer));
}
}
7、concat
  • 使用concat方法把两个流合并成一个新的流。
/**
* Stream流的concat方法:<R> Stream<R> map(Function<? super T, ? extends R> mapper);
* public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
*
* @author zhuhuix
* @date 2020-07-26
*/
public class SteamConcat {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("a", "b", "c", "d");
Stream<String> stream2 = Stream.of("A", "B", "C", "D");

// 通过静态方法concat把两个流的元素合并形成新的流
Stream<String> stream = Stream.concat(stream1, stream2);
stream.forEach(s -> System.out.println(s));
}
}

Steram流的案例

  • 统计两个班级分数超过90分以上的前三名学生
/**
* Stream流的综合案例
*
* @author zhuhuix
* @date 2020-07-26
*/
public class StreamDemo {

public static void main(String[] args) {
// 创建两个班级的学生集合
List<Student> class1 = new ArrayList<>();
class1.add(new Student("jack", 91));
class1.add(new Student("mike", 90));
class1.add(new Student("jerry", 76));
class1.add(new Student("rose", 100));

List<Student> class2 = new ArrayList<>();
class2.add(new Student("kate", 99));
class2.add(new Student("tony", 86));
class2.add(new Student("sally", 94));
class2.add(new Student("billy", 83));

// 通过流的方式得出两个班级的超过90分的前三名学生
Stream<Student> stream1 = class1.stream().filter(student -> student.score > 90);
Stream<Student> stream2 = class2.stream().filter(student -> student.score > 90);

Stream.concat(stream1, stream2).sorted((s1,s2)->s1.compareTo(s2)).forEach(student -> System.out.println(student));
}
}

class Student implements Comparable {
String name;
Integer score;

Student(String name, Integer score) {
this.name = name;
this.score = score;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getScore() {
return score;
}

public void setScore(Integer score) {
this.score = score;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}

@Override
public int compareTo(Object o) {
if (o instanceof Student){
return ((Student) o).score-this.score;
}
return -1;
}
}

深入理解Java Stream流_数据源_02