一:简介
java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行stream()执行或者并行parallelStream()执行。
二:Stream
package java.util.stream;
public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> filter(Predicate<? super T> predicate);
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
Stream<T> distinct();
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
Stream<T> peek(Consumer<? super T> action);
Stream<T> limit(long maxSize);
Stream<T> skip(long n);
void forEach(Consumer<? super T> action);
void forEachOrdered(Consumer<? super T> action);
Object[] toArray();
<A> A[] toArray(IntFunction<A[]> generator);
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
long count();
boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
Optional<T> findFirst();
Optional<T> findAny();
public static<T> Builder<T> builder() {
return new Streams.StreamBuilderImpl<>();
}
public static<T> Stream<T> empty() {
return StreamSupport.stream(Spliterators.<T>emptySpliterator(), false);
}
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
Objects.requireNonNull(f);
final Iterator<T> iterator = new Iterator<T>() {
@SuppressWarnings("unchecked")
T t = (T) Streams.NONE;
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() {
return t = (t == Streams.NONE) ? seed : f.apply(t);
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
}
public static<T> Stream<T> generate(Supplier<T> s) {
Objects.requireNonNull(s);
return StreamSupport.stream(
new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
}
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
@SuppressWarnings("unchecked")
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
return stream.onClose(Streams.composedClose(a, b));
}
public interface Builder<T> extends Consumer<T> {
@Override
void accept(T t);
default Builder<T> add(T t) {
accept(t);
return this;
}
Stream<T> build();
}
}
三:示例
1. forEach 循环
@Test
public void forEach(){
// 你不鸟我,我也不鸟你
List<String> list = Arrays.asList("you", "don't", "bird", "me", ",",
"I", "don't", "bird", "you");
// 方式一:JDK1.8之前的循环方式
for (String item: list) {
System.out.println(item);
}
// 方式二:使用Stream的forEach方法
// void forEach(Consumer<? super T> action)
list.stream().forEach(item -> System.out.println(item));
// 方式三:方式二的简化方式
// 由于方法引用也属于函数式接口,所以方式二Lambda表达式也可以使用方法引用来代替
// 此种方式就是方式一、方式二的简写形式
list.stream().forEach(System.out::println);
}
2. filter 过滤
public class User {
private Long id;
private String phone;
private Integer age;
public User(){}
public User(Long id, String username, Integer age) {
this.id = id;
this.username = username;
this.age = age;
}
// Getter & Setter & toString
}
@Test
public void filter(){
List<User> users = Arrays.asList(
new User(1L, "mengday", 28),
new User(2L, "guoguo", 18),
new User(3L, "liangliang", 17)
);
// Stream<T> filter(Predicate<? super T> predicate);
users.stream().filter(user -> user.getAge() > 18).forEach(System.out::println);
}
3. map 映射
@Test
public void map(){
List<String> list = Arrays.asList("how", "are", "you", "how", "old", "are", "you", "?");
// <R> Stream<R> map(Function<? super T, ? extends R> mapper);
list.stream().map(item -> item.toUpperCase()).forEach(System.out::println);
}
4. flatMap
@Test
public void flatMap(){
List<Integer> a = Arrays.asList(1, 2, 3);
List<Integer> b = Arrays.asList(4, 5, 6);
// <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
List<List<Integer>> collect = Stream.of(a, b).collect(Collectors.toList());
// [[1, 2, 3], [4, 5, 6]]
System.out.println(collect);
// 将多个集合中的元素合并成一个集合
List<Integer> mergeList = Stream.of(a, b).flatMap(list -> list.stream()).collect(Collectors.toList());
// [1, 2, 3, 4, 5, 6]
System.out.println(mergeList);
// 通过Builder模式来构建
Stream<Object> stream = Stream.builder().add("hello").add("hi").add("byebye").build();
}
5. sorted 排序
@Test
public void sort(){
List<String> list = Arrays.asList("c", "e", "a", "d", "b");
// Stream<T> sorted(Comparator<? super T> comparator);
// int compare(T o1, T o2);
list.stream().sorted((s1, s2) -> s1.compareTo(s2)).forEach(System.out::println);
}
6. distinct 去重复
@Test
public void distinct(){
// 知之为知之,不知为不知
Stream<String> stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
stream.distinct().forEach(System.out::println); // know is noknow
}
7. count 总数量
@Test
public void count(){
Stream<String> stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
long count = stream.count();
System.out.println(count);
}
8. min、max
@Test
public void min(){
List<String> list = Arrays.asList("1", "2", "3", "4", "5");
// Optional<T> min(Comparator<? super T> comparator);
Optional<String> optional = list.stream().min((a, b) -> a.compareTo(b));
String value = optional.get();
System.out.println(value);
}
9. skip、limit
@Test
public void skip(){
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
// Stream<T> skip(long n)
list.stream().skip(2).forEach(System.out::println); // c、d、e
}
@Test
public void limit(){
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.stream().skip(2).limit(2).forEach(System.out::println); // c、d
}
10. collect
@Test
public void collect(){
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
// Stream -> Collection
List<String> collect = list.stream().collect(Collectors.toList());
// Stream -> Object[]
Object[] objects = list.stream().toArray();
}
11. concat
@Test
public void concat(){
List<String> list = Arrays.asList("a", "b");
List<String> list2 = Arrays.asList("c", "d");
Stream<String> concatStream = Stream.concat(list.stream(), list2.stream());
concatStream.forEach(System.out::println);
}
12. anyMatch、allMatch
@Test
public void match(){
// 你给我站住
List<String> list = Arrays.asList("you", "give", "me", "stop");
// boolean anyMatch(Predicate<? super T> predicate);
// parallelStream可以并行计算,速度比stream更快
boolean result = list.parallelStream().anyMatch(item -> item.equals("me"));
System.out.println(result);
}
/**
* anyMatch伪代码
* 如果集合中有一个元素满足条件就返回true
* @return
*/
public boolean anyMatch() {
List<String> list = Arrays.asList("you", "give", "me", "stop");
for (String item : list) {
if (item.equals("me")) {
return true;
}
}
return false;
}
13. reduce 归纳
@Test
public void reduce(){
Stream<String> stream = Stream.of("you", "give", "me", "stop");
// Optional<T> reduce(BinaryOperator<T> accumulator);
Optional<String> optional = stream.reduce((before, after) -> before + "," + after);
optional.ifPresent(System.out::println); // you,give,me,stop
}
BigDecimal求和
public static void main(String[] args) {
List<BigDecimal> list = Arrays.asList(
new BigDecimal("11.11"),
new BigDecimal("22.22"),
new BigDecimal("33.33")
);
// 66.66
BigDecimal sum = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(sum);
}
14. findFirst、findAny
@Test
public void findFirst(){
Stream<String> stream = Stream.of("you", "give", "me", "stop");
String value = stream.findFirst().get();
System.out.println(value);
}
@Test
public void findAny(){
Stream<String> stream = Stream.of("you", "give", "me", "stop");
// 返回任意一个
String value2 = stream.findAny().get();
stream.findAny().orElse("默认值");
System.out.println(value2);
}
15. peek
tream.of("You", "give", "me", "GUN")
.map(String::toUpperCase)
.peek(item -> System.out.println(item))
.peek(String::toLowerCase)
.collect(Collectors.toList());
peek和forEach的功能类似,会循环每个元素,然后可以对每个元素进行操作(如打印值,或者修改元素的值),不同的是peek()返回的Stream,而forEach返回的是void,即peek()是中间态,forEach是终止态。
public class User {
private Long id;
private String phone;
private String username;
private String nickname;
private Integer age;
// 提供一个接收当前对象的构造函数
private User(Builder builder) {
this.id = builder.id;
this.phone = builder.phone;
this.username = builder.username;
this.nickname = builder.nickname;
this.age = builder.age;
}
// Getter & Setter
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
// 静态内部类 Builder
// User的创建完全依靠User.Builder,使用一种方法链的方式来创建
public static class Builder {
private Long id;
private String phone;
private String username;
private String nickname;
private Integer age;
// Setter方法,方法名为属性名,方法返回Builder对象
public Builder id(Long id) {
this.id = id;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder username(String username) {
this.username = username;
return this;
}
public Builder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public Builder age(Integer age) {
this.age = age;
return this;
}
// build 方法
public User build(){
return new User(this);
}
}
}
public class Order {
private Long id;
private String orderNo;
private Date createTime;
private BigDecimal amout;
Order(Long id, String orderNo, Date createTime, BigDecimal amout) {
this.id = id;
this.orderNo = orderNo;
this.createTime = createTime;
this.amout = amout;
}
public Long getId() {
return id;
}
public String getOrderNo() {
return orderNo;
}
public Date getCreateTime() {
return createTime;
}
public BigDecimal getAmout() {
return amout;
}
public static Order.OrderBuilder builder() {
return new Order.OrderBuilder();
}
public static class OrderBuilder {
private Long id;
private String orderNo;
private Date createTime;
private BigDecimal amout;
OrderBuilder() {
}
public Order.OrderBuilder id(Long id) {
this.id = id;
return this;
}
public Order.OrderBuilder orderNo(String orderNo) {
this.orderNo = orderNo;
return this;
}
public Order.OrderBuilder createTime(Date createTime) {
this.createTime = createTime;
return this;
}
public Order.OrderBuilder amout(BigDecimal amout) {
this.amout = amout;
return this;
}
public Order build() {
return new Order(this.id, this.orderNo, this.createTime, this.amout);
}
public String toString() {
return "Order.OrderBuilder(id=" + this.id + ", orderNo=" + this.orderNo + ", createTime=" + this.createTime + ", amout=" + this.amout + ")";
}
}
}
public class Main {
public static void main(String[] args) {
User user = new User.Builder().id(1L).phone("666").nickname("mengday").age(18).build();
Order order = Order.builder().id(1L).orderNo("1111").build();
order = new Order.OrderBuilder().id(1L).orderNo("1111").build();
}
}