1、Stream流
是JDK1.8 之后出现的,它是一个来自数据源的元素队列。其中,数据源也就是流的来源,可以是集合、数组等;元素是特定类型的对象,形成一个队列。
注意,在Java中,Stream并不会存储元素,而是按需进行计算。
2、Stream的基本特征
(1)Pipelining:在流上,中间的操作都会返回流对象本身,使得多个操作可以串联成一个管道,对操作进行优化。
(2)内部迭代:流可以直接调用遍历方法,实现内部迭代。
当使用一个流时,通常包括三个基本步骤:获取一个数据源(source)-> 数据转换 -> 执行操作,获取想要的结果。每次转换原有的Stream流对象不变,而是返回一个新的Stream流对象,这就允许对其操作可以像链条一样排列,变成一个管道。
3、获取流的两种方式
(1)所有的Collection集合都可以通过Stream默认方法获取流。
default Stream<T> stream()
public class Test{
public static void main(String[] args) {
String[] arr = {"abc","bcd","cde","def"};
ArrayList<String> array = new ArrayList<>();
array.add("one");
array.add("two");
Stream<String> stream1 = array.stream();
Set<Integer> set = new HashSet<>();
Stream<Integer> stream2 = set.stream();
Stream<String> stream3 = Arrays.stream(arr);
}
}
(2)Stream流的静态方法 of 可以获取数组对应的流对象
static<T> Stream<T> of(T ...values)
public class Test {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<String> stream1 = Stream.of("one", "two", "three", "four", "five", "six");
}
}
Stream流属于管道流,只能被消费一次,第一个Stream流调用完毕之后,数据就会流向下一个新Stream流上,此时第一个Stream流已经使用完毕,关闭了,即不能第一个Stream流对象不能再调用其他的方法了。
3、常用方法
(1)终结方法:返回值类型不是Stream接口自身类型的方法,因此不支持链式调用。
<1> forEach():逐一处理,用来遍历流中的数据,接收一个Consumer接口函数,会将每一个元素交给该函数处理。
void forEach(Consumer<? super T> action);
<2> count():获取流中元素的个数,返回一个long型数据。
public class Test {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<String> stream1 = Stream.of("one", "two", "three", "four", "five", "six");
stream.forEach((num)-> System.out.println(num));
long count = stream1.count();
System.out.println(count);
}
}
(2)延迟方法:返回值类型依然是Stream接口自身类型的方法,因此支持链式调用。
<1> filter() : 将一个流转换成一个子集流。
Stream<T> filter(Predicate<? super T> predicate);
<2> map() :该方法需要一个Function函数式接口参数,可以将当前流中T类型的数据转换为另一种R类型的数据。
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
<3> limit() : 截取流中的前n个数据。
Stream<T> limit(long maxSize);
<4> skip() : 如果当前流中元素个数大于n,则跳过前n个元素,否则得到一个长度为0空流。
Stream<T> skip(long n);
<5> concat() : 将两个流合并成一个流。
public class Test {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<String> stream1 = Stream.of("one", "two", "three", "four", "five", "six");
Stream<Integer> stream2 = stream.filter((num) -> num > 2);//3、4,5,6
Stream<String> stream3 = stream2.map((num) -> num.toString());//将整型转换为String类型,3,4,5,6
Stream<String> stream4 = stream1.limit(5);//("one", "two", "three", "four", "five")
Stream<String> stream5 = stream4.skip(2);//("three", "four", "five")
Stream<String> stream6 = Stream.concat(stream3, stream5);//3,4,5,6,three,four,five,
stream6.forEach((str)-> System.out.print(str + ","));
}
}