JDK8新特性之Optional类与Stream流

Optional类

以前对null的处理方式:


public class Test {
    public static void main(String[] args) {
        String userName = "凤姐";
        // String userName = null;
        if (userName != null) {
            System.out.println("用户名为:" + userName);
        } else {
            System.out.println("用户名不存在");
        }
    }
}
//控制台打印:用户名为:凤姐

Optional类介绍
Optional是一个没有子类的工具类,Optional是一个可以为null的容器对象。它的作用主要就是为了解决避免Null检查,防止NullPointerException。
在这里插入图片描述
Optional类的创建方式:

Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例

Optional类的常用方法:

isPresent() : 判断是否包含值,包含值返回true,不包含值返回false
get() : 如果Optional有值则将其返回,否则抛出NoSuchElementException
orElse(T t) : 如果调用对象包含值,返回该值,否则返回参数t
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
import java.util.Optional;

public class Test {
    public static void main(String[] args) {
        // Optional<String> userNameO = Optional.of("凤姐");
        // Optional<String> userNameO = Optional.of(null);
        // Optional<String> userNameO = Optional.ofNullable(null);
        Optional<String> userNameO = Optional.empty();
        // isPresent() : 判断是否包含值,包含值返回true,不包含值返回false。
        if (userNameO.isPresent()) {
            // get() : 如果Optional有值则将其返回,否则抛出NoSuchElementException。
            String userName = userNameO.get();
            System.out.println("用户名为:" + userName);
        } else {
            System.out.println("用户名不存在");
        }
    }
}
//控制台输出:用户名不存在
import java.util.Optional;

public class Test {
    public static void main(String[] args) {
        Optional<String> userName0 = Optional.of("张三");
        Optional<String> userName1 = Optional.empty();
        // 如果调用对象包含值,返回该值,否则返回参数t
        System.out.println("用户名为" + userName0.orElse("null"));
        System.out.println("用户名为" + userName1.orElse("null"));

        //如果调用对象包含值,返回该值,否则返回 s 获取的值,public T orElseGet(Supplier<? extends T> other),可用Lambda表达式
        String s1 = userName0.orElseGet(() -> {return "未知用户名";});
        System.out.println("s1 = " + s1);
    }
}
//控制台打印:
用户名为张三
用户名为null
s1 = 张三

Optional是一个可以为null的容器对象!

Stream流

import java.util.ArrayList;
import java.util.Collections;

public class Test {
    public static void main(String[] args) {
        // 一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
        // 需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
        // 1.拿到所有姓张的
        ArrayList<String> zhangList = new ArrayList<>(); // {"张无忌", "张强", "张三丰"}
        for (String name : list) {
            if (name.startsWith("张")) {
                zhangList.add(name);
            }
        }
        // 2.拿到名字长度为3个字的
        ArrayList<String> threeList = new ArrayList<>(); // {"张无忌", "张三丰"}
        for (String name : zhangList) {
            if (name.length() == 3) {
                threeList.add(name);
            }
        }
        // 3.打印这些数据
        for (String name : threeList) {
            System.out.println(name);
        }
    }
}
//控制台打印:
张无忌
张三丰

每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使用另一个循环从头开始。

Stream的写法:

import java.util.ArrayList;
import java.util.Collections;

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
        list.stream()
                .filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(System.out::println);
    }
}
//控制台打印:
张无忌
张三丰

直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印。

Stream流式思想概述

注意:Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!

Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。
在这里插入图片描述
Stream API能让我们快速完成许多复杂的操作,如筛选、切片、映射、查找、去除重复,统计,匹配和归约;

获取Stream流的两种方式

java.util.stream.Stream 是JDK 8新加入的流接口;

获取一个流非常简单,有以下几种常用的方式:

  1. 所有的 Collection 集合都可以通过 stream 默认方法获取流;
  2. Stream 接口的静态方法 of 可以获取数组对应的流;

根据Collection获取流:
java.util.Collection 接口中加入了default方法 stream 用来获取流,所以其所有实现类均可获取流:

public interface Collection {
default Stream<E> stream()
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // 集合获取流
        // Collection接口中的方法: default Stream<E> stream() 获取流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        //Set获取流
        Set<String> set = new HashSet<>();
        Stream<String> stream2 = set.stream();

        //Vector获取流
        Vector<String> vector = new Vector<>();
        Stream<String> stream3 = vector.stream();

        //java.util.Map 接口不是 Collection 的子接口,所以获取对应的流需要分key、value或entry等情况:
        Map<String, String> map = new HashMap<>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<String> valueStream = map.values().stream();
        Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
    }
}

Stream中的静态方法of获取流
由于数组对象不可能添加默认方法,所以 Stream 接口中提供了静态方法 of ,使用很简单:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // Stream中的静态方法: static Stream of(T... values)
        Stream<String> stream6 = Stream.of("aa", "bb", "cc");
        String[] arr = {"aa", "bb", "cc"};
        Stream<String> stream7 = Stream.of(arr);
        Integer[] arr2 = {11, 22, 33};
        Stream<Integer> stream8 = Stream.of(arr2);
        // 注意:基本数据类型的数组不行
        int[] arr3 = {11, 22, 33};
        Stream<int[]> stream9 = Stream.of(arr3);

        //会报错
        Integer[] arr4 = {11, 22, 33};
        Stream<int[]> stream10 = Stream.of(arr4);
    }
}

Stream常用方法

Stream流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:

方法名方法作用返回值类型方法种类
count统计个数long终结
forEach逐一处理void终结
filter过滤Stream函数拼接
limit取用前几个Stream函数拼接
skip跳过前几个Stream函数拼接
map映射Stream函数拼接
concat组合Stream函数拼接
  1. 终结方法:返回值类型不再是 Stream 类型的方法,不再支持链式调用。本小节中,终结方法包括 count 和forEach 方法;
  2. 非终结方法:返回值类型仍然是 Stream 类型的方法,支持链式调用。(除了终结方法外,其余方法均为非终结方法);

Stream注意事项(重要):

  1. Stream只能操作一次;
  2. Stream方法返回的是新的流;
  3. Stream不调用终结方法,中间的操作不会执行

Stream流的forEach方法

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
        //Lambda表达式
        one.stream().forEach((String s) ->{
            System.out.println(s);
        });
        // 简写
        one.stream().forEach(s -> System.out.println(s));
        //方法引用
        one.stream().forEach(System.out::println);
    }
}
//控制台输出:
迪丽热巴
宋远桥
苏星河
老子
庄子
孙子

Stream流的count方法
Stream流提供 count 方法来统计其中的元素个数:

long count();

该方法返回一个long值代表元素个数。基本使用:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
        System.out.println(one.stream().count());
    }
}
//控制台输出:6

Stream流的filter方法
filter用于过滤数据,返回符合过滤条件的数据:
在这里插入图片描述
可以通过 filter 方法将一个流转换成另一个子集流。方法声明:

Stream<T> filter(Predicate<? super T> predicate);

该接口接收一个 Predicate 函数式接口参数(可以是一个Lambda或方法引用)作为筛选条件。Stream流中的 filter 方法基本使用的代码如:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
        one.stream().filter(s -> s.length() == 2).forEach(System.out::println);
    }
}
//控制台输出:
老子
庄子
孙子

在这里通过Lambda表达式来指定了筛选的条件:姓名长度为2个字。

Stream流的limit方法
在这里插入图片描述
limit 方法可以对流进行截取,只取用前n个。方法签名:

Stream<T> limit(long maxSize);

参数是一个long型,如果集合当前长度大于参数则进行截取。否则不进行操作。基本使用:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
        one.stream().limit(3).forEach(System.out::println);
    }
}
//控制台输出:
迪丽热巴
宋远桥
苏星河

Stream流的skip方法
在这里插入图片描述
如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流:

Stream<T> skip(long n);

如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。基本使用:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
        one.stream().skip(5).forEach(System.out::println);
    }
}
//控制台输出:孙子

Stream流的map方法
在这里插入图片描述
如果需要将流中的元素映射到另一个流中,可以使用 map 方法。方法签名:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

Stream流中的 map 方法基本使用的代码如:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream<String> original = Stream.of("11", "22", "33");
        Stream<Integer> result = original.map(Integer::parseInt);
        result.forEach(s -> System.out.println(s + 10));
    }
}
//控制台打印:
21
32
43

Stream流的sorted方法
如果需要将数据排序,可以使用 sorted 方法。方法签名:

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

Stream流中的 sorted 方法基本使用的代码如:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        // sorted(): 根据元素的自然顺序排序
        // sorted(Comparator<? super T> comparator): 根据比较器指定的规则排序
        Stream.of(33, 22, 11, 55)
                .sorted()
                .sorted((o1, o2) -> o2 - o1)
                .forEach(System.out::println);
    }
}
//控制台打印:55 33 22 11

sorted 方法根据元素的自然顺序排序,也可以指定比较器排序;

Stream流的distinct方法
在这里插入图片描述
如果需要去除重复数据,可以使用 distinct 方法。方法签名:

Stream<T> distinct();

Stream流中的 distinct 方法基本使用的代码如:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream.of(22, 33, 22, 11, 33)
                .distinct()
                .forEach(System.out::println);
    }
}
//控制台打印:22 33 11

如果是自定义类型如何是否也能去除重复的数据呢?

public class Person {
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
	// 省略set/get
}
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream.of(
                new Person("刘德华", 58),
                new Person("张学友", 56),
                new Person("张学友", 56),
                new Person("黎明", 52))
                .distinct()
                .forEach(System.out::println);
    }
}
//控制台打印:
Person@448139f0
Person@7cca494b
Person@7ba4f24f
Person@3b9a45b3

发现并没有清除,自定义类型是根据对象的hashCode和equals来去除重复元素的,重写Person类的equals()与hashCode():

import java.util.Objects;

public class Person {
    private String name;
    private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    @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);
    }

}

再运行main方法,控制台打印:
Person@26c2bf4c
Person@2c9f1054
Person@26082f5

发现重复的已经被去除;

Stream流的match方法
如果需要判断数据是否匹配指定的条件,可以使用 Match 相关方法。方法签名:

boolean allMatch(Predicate<? super T> predicate);
boolean anyMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);

Stream流中的 Match 相关方法基本使用的代码如:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        boolean b = Stream.of(5, 3, 6, 1)
        // .allMatch(e -> e > 0); // allMatch: 元素是否全部满足条件
        // .anyMatch(e -> e > 5); // anyMatch: 元素是否任意有一个满足条件
                .noneMatch(e -> e < 0); // noneMatch: 元素是否全部不满足条件
        System.out.println("b = " + b);
    }
}
//控制台打印:b = true

Stream流的find方法
在这里插入图片描述

如果需要找到某些数据,可以使用 find 相关方法。方法签名:

Optional<T> findFirst();
Optional<T> findAny();
import java.util.Optional;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Optional<Integer> first = Stream.of(5, 3, 6, 1).findFirst();
        System.out.println("first = " + first.get());
        Optional<Integer> any = Stream.of(5, 3, 6, 1).findAny();  //默认找第一个
        System.out.println("any = " + any.get());
    }
}
//控制台打印:
first = 5
any = 5

Stream流的max和min方法

如果需要获取最大和最小值,可以使用 max 和 min 方法。方法签名:

Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);

Stream流中的 max 和 min 相关方法基本使用的代码如:

import java.util.Optional;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Optional<Integer> max = Stream.of(5, 3, 6, 1).max((o1, o2) -> o1 - o2);
        System.out.println("first = " + max.get());
        Optional<Integer> min = Stream.of(5, 3, 6, 1).min((o1, o2) -> o1 - o2);
        System.out.println("any = " + min.get());

    }
}
//控制台打印:
first = 6
any = 1

Stream流的reduce方法

T reduce(T identity, BinaryOperator<T> accumulator);

Stream流中的 reduce 相关方法基本使用的代码如:

import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        //Lambda表达式
        int reduce = Stream.of(4, 5, 3, 9)
                .reduce(0, (a, b) -> {
                    System.out.println("a = " + a + ", b = " + b);
                    return a + b;
                });
        // reduce:
        // 第一次将默认做赋值给x, 取出第一个元素赋值给y,进行操作
        // 第二次,将第一次的结果赋值给x, 取出二个元素赋值给y,进行操作
        // 第三次,将第二次的结果赋值给x, 取出三个元素赋值给y,进行操作
        // 第四次,将第三次的结果赋值给x, 取出四个元素赋值给y,进行操作
        System.out.println("reduce = " + reduce);
        //Lambda表达式简化
        int reduce2 = Stream.of(4, 5, 3, 9)
                .reduce(0, (x, y) -> {
                    return Integer.sum(x, y);
                });
        //方法引用
        int reduce3 = Stream.of(4, 5, 3, 9).reduce(0, Integer::sum);
        int max = Stream.of(4, 5, 3, 9)
                .reduce(0, (x, y) -> {
                    return x > y ? x : y;
                });
        System.out.println("max = " + max);

    }
}
//控制台输出:
a = 0, b = 4
a = 4, b = 5
a = 9, b = 3
a = 12, b = 9
reduce = 21
max = 9

Stream流的concat方法

如果有两个流,希望合并成为一个流,那么可以使用 Stream 接口的静态方法 concat :

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream<String> streamA = Stream.of("张三");
        Stream<String> streamB = Stream.of("李四");
        Stream<String> result = Stream.concat(streamA, streamB);
        result.forEach(System.out::println);
        Long count =  streamA.count();
        System.out.println(count);
    }
}

合并产生一个新的流,但是之前的流就已经被关闭了,再进行操作将会报错:

张三
李四
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
	at java.util.stream.LongPipeline.<init>(LongPipeline.java:91)
	at java.util.stream.LongPipeline$StatelessOp.<init>(LongPipeline.java:574)
	at java.util.stream.ReferencePipeline$5.<init>(ReferencePipeline.java:221)
	at java.util.stream.ReferencePipeline.mapToLong(ReferencePipeline.java:220)
	at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526)
	at Test.main(Test.java:9)

Stream综合案例

现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)依次进行以下
若干操作步骤:

  1. 第一个队伍只要名字为3个字的成员姓名;
  2. 第一个队伍筛选之后只要前3个人;
  3. 第二个队伍只要姓张的成员姓名;
  4. 第二个队伍筛选之后不要前2个人;
  5. 将两个队伍合并为一个队伍;
  6. 根据姓名创建 Person 对象;
  7. 打印整个队伍的Person对象信息。

两个队伍(集合)的代码如下:

List<String> one = List.of("迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子", "洪七公");
List<String> two = List.of("古力娜扎", "张无忌", "张三丰", "赵丽颖", "张二狗", "张天爱","张三");

Person.java:

public class Person {
private String name;
}

传统方式:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        List<String> two = new ArrayList<>();
        Collections.addAll(one,"迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子", "洪七公");
        Collections.addAll(two,"古力娜扎", "张无忌", "张三丰", "赵丽颖", "张二狗", "张天爱", "张三");
        // 第一个队伍只要名字为3个字的成员姓名;
        List<String> oneA = new ArrayList<>();
        for (String name : one) {
            if (name.length() == 3) {
                oneA.add(name);
            }
        }
        // 第一个队伍筛选之后只要前3个人;
        List<String> oneB = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            oneB.add(oneA.get(i));
        }
        // 第二个队伍只要姓张的成员姓名;
        List<String> twoA = new ArrayList<>();
        for (String name : two) {
            if (name.startsWith("张")) {
                twoA.add(name);
            }
        }
        // 第二个队伍筛选之后不要前2个人;
        List<String> twoB = new ArrayList<>();
        for (int i = 2; i < twoA.size(); i++) {
            twoB.add(twoA.get(i));
        }
        // 将两个队伍合并为一个队伍;
        List<String> totalNames = new ArrayList<>();
        totalNames.addAll(oneB);
        totalNames.addAll(twoB);
        // 根据姓名创建Person对象;
        List<Person> totalPersonList = new ArrayList<>();
        for (String name : totalNames) {
            totalPersonList.add(new Person(name));
        }
        // 打印整个队伍的Person对象信息。
        for (Person person : totalPersonList) {
            System.out.println(person);
        }
    }
}
//控制台打印:
Person{name='宋远桥'}
Person{name='苏星河'}
Person{name='洪七公'}
Person{name='张二狗'}
Person{name='张天爱'}
Person{name='张三'}

Stream方式:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        List<String> two = new ArrayList<>();
        Collections.addAll(one,"迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子", "洪七公");
        Collections.addAll(two,"古力娜扎", "张无忌", "张三丰", "赵丽颖", "张二狗", "张天爱", "张三");
        // 第一个队伍只要名字为3个字的成员姓名;
        // 第一个队伍筛选之后只要前3个人;
        Stream<String> streamOne = one.stream().filter(s -> s.length() == 3).limit(3);
        // 第二个队伍只要姓张的成员姓名;
        // 第二个队伍筛选之后不要前2个人;
        Stream<String> streamTwo = two.stream().filter(s -> s.startsWith("张")).skip(2);
        // 将两个队伍合并为一个队伍;
        // 根据姓名创建Person对象;
        // 打印整个队伍的Person对象信息。
        Stream.concat(streamOne, streamTwo).map(Person::new).forEach(System.out::println);
    }
}
//控制台打印与上面是一样的

Stream流中的结果到集合中

Stream流提供 collect 方法,其参数需要一个 java.util.stream.Collector<T,A, R> 接口对象来指定收集到哪种集合中。java.util.stream.Collectors 类提供一些方法,可以作为 Collector`接口的实例:

public static <T> Collector<T, ?, List<T>> toList() :转换为 List 集合。
public static <T> Collector<T, ?, Set<T>> toSet() :转换为 Set 集合。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("aa", "bb", "cc");
        //转换为 List 集合。
        List<String> list = stream.collect(Collectors.toList());
        //转换为 Set 集合。
        Set<String> set = stream.collect(Collectors.toSet());
        //转换为 ArrayList集合。
        ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
        //转换为 HashSet集合。
        HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
    }
}

Stream流中的结果到数组中

Stream提供 toArray 方法来将结果放到一个数组中,返回值类型是Object[]的:

Object[] toArray();
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("aa", "bb", "cc");
        //Object类型的数组
        // Object[] objects = stream.toArray();
        // for (Object obj : objects) {
        // System.out.println();
        // }
        //转为String类型的数组
        String[] strings = stream.toArray(String[]::new);
        for (String str : strings) {
            System.out.println(str);
        }
    }
}
//控制台打印:
aa
bb
cc
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值