Stream(流)是一个支持顺序和平行聚合操作的元素序列,和java.util.List类似,是jdk1.8的新特性。可以看出Stream还有几个兄弟类IntStream、LongStream和DoubleStream。
/**
* @param <T> the type of the stream elements
* @since 1.8
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface Stream<T> extends BaseStream<T, Stream<T>> {
......
}
本章主要以集合流来介绍Stream的详细使用
目录
一、实例方法
操作类方法
转换类方法
遍历类方法
获取类方法
判断类方法
二、静态方法
一、实例方法
操作类方法
1、Stream<T> filter(Predicate<? super T> predicate);
过滤掉流中不符合断言规则的元素,得到一个新的Stream对象
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
Stream<String> stringStream = stream.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("o");
}
});
System.out.println(
Arrays.toString(
stringStream.toArray()
)
);
}
}
以上代码的作用是输出集合list中包含字符串"o"的元素。
运行结果:
[Hello, Tom, Jhon, Jackson, Jackson, Jackson]
2、Stream<T> distinct();
去重
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
System.out.println(
Arrays.toString(
stream.distinct().toArray()
)
);
}
}
去重后,只有一个Jackson
[Hello, Tom, Marry, Jhon, Lisa, Jim, Jackson]
3、Stream<T> sorted();
对流的元素排序,如果是字母,按照字母的顺序从a~z、A~Z排序
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
System.out.println(
Arrays.toString(
stream.sorted().toArray()
)
);
}
}
排序后,打印结果为
[Hello, Jackson, Jackson, Jackson, Jhon, Jim, Lisa, Marry, Tom]
4、Stream<T> sorted(Comparator<? super T> comparator);
排序,并自定义排序规则,Comparator应该都不陌生——比较器接口,在集合的排序方法Collections.sort()中就用到了
如:按照字符串长度排序
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
System.out.println(
Arrays.toString(
stream.sorted(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
}).toArray()
)
);
}
}
长度相同的按照原有的先后顺序排序,运行结果如下
[Tom, Jim, Jhon, Lisa, Hello, Marry, Jackson, Jackson, Jackson]
5、Stream<T> peek(Consumer<? super T> action);
元素遍历,这里有涉及到了Consumer函数这个接口,和Function接口的功能几乎一样
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
stream.peek(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s.toLowerCase());
}
}).toArray();
}
}
以上代码把元素全部转为小写字母然后打印
hello
tom
marry
jhon
lisa
jim
jackson
jackson
jackson
6、Stream<T> limit(long maxSize);
修改Stream中元素的个数
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
System.out.println(
Arrays.toString(
stream.limit(5).toArray()
)
);
}
}
最后只保留了前5个元素,运行结果如下
[Hello, Tom, Marry, Jhon, Lisa]
7、Stream<T> skip(long n);
跳过前n个元素,也就是删除前n个元素
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
System.out.println(
Arrays.toString(
stream.skip(5).toArray()
)
);
}
}
跳过了前五个元素,就只剩下最后四个元素
[Jim, Jackson, Jackson, Jackson]
转换类方法
1、<R> Stream<R> map(Function<? super T, ? extends R> mapper);
用于转化流的类型,得到的Stream对象类型为R,也就是Function的返回值类型
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
Stream<Boolean> booleanStream = stream.map(new Function<String, Boolean>() {
@Override
public Boolean apply(String s) {
return s.equals("Hello");
}
});
System.out.println(
Arrays.toString(
booleanStream.toArray()
)
);
}
}
显然,只有第一个元素为true,其他都是false
[true, false, false, false, false, false, false, false, false]
2、IntStream mapToInt(ToIntFunction<? super T> mapper);
转为IntStream 对象
3、LongStream mapToLong(ToLongFunction<? super T> mapper);
转为LongStream 对象
4、DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
转为DoubleStream 对象
5、<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
批量操作流中的所有元素,得到一个新的流对象
6、IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
作用同mapToInt()
7、LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
作用同mapToLong()
8、DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
作用同mapToDouble()
9、Object[] toArray();
使用当前Stream对象的所有元素生成一个数组,整篇文章基本都在使用这个方法,就不过多介绍了。
10、<A> A[] toArray(IntFunction<A[]> generator);
作用和上一个方法一样,参数类型A要求是当前Stream对象的泛型的超类,否则会抛出
ArrayStoreException异常,下面的代码将得到包含Stream对象里所以元素的数组并遍历打印
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
String[] array = stream.toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[list.size()];
}
});
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
11、Optional<T> reduce(BinaryOperator<T> accumulator);
对当前Stream对象的所有元素执行一定操作,得到一个Optional对象,操作的结果就是Optional对象的value值。
例如,把Stream对象的元素拼接起来得到一个Optinal对象
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
Optional<String> optional = stream.reduce(new BinaryOperator<String>() {
@Override
public String apply(String s, String s2) {
return s.concat(s2);
}
});
System.out.println(optional.get());
}
}
运行结果
HelloTomMarryJhonLisaJimJacksonJacksonJackson
12、T reduce(T identity, BinaryOperator<T> accumulator);
该方法作用和上一个方法一样,但是可以指定返回值类型,返回值类型就是第一个参数的类型
import java.util.ArrayList;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
String result = stream.reduce("", new BinaryOperator<String>() {
@Override
public String apply(String s, String s2) {
return s.concat(s2);
}
});
System.out.println(result);
}
}
运行结果和上一个方法一样,都是把Stream对象的所有元素拼接起来
HelloTomMarryJhonLisaJimJacksonJacksonJackson
13、<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
14、<R, A> R collect(Collector<? super T, A, R> collector);
15、<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
遍历类方法
1、void forEach(Consumer<? super T> action);
很明显,这个方法就是用来遍历当前Stream对象里的元素
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
stream.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
直接打印所有的元素
Hello Tom Marry Jhon Lisa Jim Jackson Jackson Jackson
2、void forEachOrdered(Consumer<? super T> action);
按正序遍历元素,同forEach()
package test;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("Tom");
list.add("Marry");
list.add("Jhon");
list.add("Lisa");
list.add("Jim");
list.add("Jackson");
list.add("Jackson");
list.add("Jackson");
Stream<String> stream = list.stream();
stream.forEachOrdered(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
运行结果和上一个方法一样
获取类方法
1、Optional<T> min(Comparator<? super T> comparator);
获取当前Stream对象中元素的最小值
2、Optional<T> max(Comparator<? super T> comparator);
获取当前Stream对象中元素的最大值
3、long count();
获取当前Stream对象中元素的个数,用法很简单,就不贴代码了
4、Optional<T> findFirst();
得到一个包含当前Stream对象的第一个元素的Optinal对象
5、Optional<T> findAny();
得到一个包含当前Stream对象的任意一个元素的Optinal对象
判断类方法
1、boolean anyMatch(Predicate<? super T> predicate);
判断当前Stream对象的元素中有没有元素符合断言,如果有,则返回true,否则返回false
2、boolean allMatch(Predicate<? super T> predicate);
判断当前Stream对象的元素是否全部符合断言,如果是,返回true,否则返回false
3、boolean noneMatch(Predicate<? super T> predicate);
该方法和anyMatch()相反,没有元素符合断言返回true,否则返回false
二、静态方法
1、static<T> Stream<T> empty()
返回一个空的顺序流
2、static<T> Stream<T> of(T t)
指定元素创建一个顺序流
3、static<T> Stream<T> of(T... values)
通过指定的多个元素创建一个顺序流