> 文章列表 > Java核心技术知识点笔记—Java SE 8的流库(二)

Java核心技术知识点笔记—Java SE 8的流库(二)

Java核心技术知识点笔记—Java SE 8的流库(二)

前言:约简是一种终结操作(terminal operation),它们会将流约简为可以在程序中使用的非流值。例如:Stream中的count方法,返回流中元素的数量。

1、简单约简举例:

(1)Optional<T> max(Comparator<? super T> comparator):使用给定的comparator规则,产生流的最大元素,如果流为空,则产生一个空的Optional对象

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
Optional<String> optional = stream.max(String::compareToIgnoreCase);
System.out.print("max: " + optional.orElse(""));

(2)Optional<T> min(Comparator<? super T> comparator):使用给定的comparator规则,产生流的最小元素,如果流为空,则产生一个空的Optional对象。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
Optional<String> optional = stream.min(String::compareToIgnoreCase);
System.out.print("min: " + optional.orElse(""));

(3)Optional<T> findFirst():产生流的第一个元素,如果流为空,则产生一个空的Optional对象。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
Optional<String> optional = stream.filter(s->s.length()>5).findFirst();
System.out.print("findFirst: " + optional.orElse(""));

(4)Optional<T> findAny():产生流的任意一个元素,如果流为空,则产生一个空的Optional对象。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
Optional<String> optional = stream.filter(s->s.length()>5).findAny();
System.out.print("findFirst: " + optional.orElse(""));

(5)boolean anyMatch(Predicate<? super T> predicate):判断流中是否有任意元素符合给定规则predicate,如果有返回true,如果没有返回false。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
boolean anyMatch = stream.anyMatch(s -> s.length() > 5);
System.out.print("anyMatch: " + anyMatch);

(6)boolean allMatch(Predicate<? super T> predicate):判断流中元素是否全部符合给定规则predicate,如果全部符合返回true,否则返回false。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
boolean allMatch = stream.allMatch(s -> s.length() > 51);
System.out.print("allMatch: " + allMatch);

(7)boolean noneMatch(Predicate<? super T> predicate):判断流中是否没有任何元素符合给定规则predicate,如果是返回true,否则返回false。

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
boolean noneMatch = stream.noneMatch(s -> s.length() > 51);
System.out.print("noneMatch: " + noneMatch);

2、Optional类型:Optional<T>对象是一种包装器对象,可以包装类型T的对象,或者没有包装任何对象。当包装了对象时,称之为值是存在的。Optional<T>类型被当作一种用来替代类型T的引用的更安全的方式,但是,只有在正确的情况下使用才能真正地更安全。

2.1、如何使用Optional值:有效使用Optional的关键在于:

(1)当值不存在时,会产生一个可替代物;

(2)只有当值存在时,才会使用这个值。

示例(1):通常,我们习惯在某个值不存在时使用默认值,或者进行某些默认的操作,比如对于某个可能存在可能不存在的字符串值:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
//获取流中长度大于20的任意字符串,包装到一个Optional对象中
Optional<String> optional = stream.filter(s -> s.length() > 20).findAny();
//当值不存在时,使用空字符串作为默认值
String orElse = optional.orElse("");
//当值不存在时,通过调用其他代码产生一个默认值
optional.orElseGet(() -> {return "optional中没有值,通过调用其他代码来产生一个默认值";
});
//当值不存在时,抛出一个异常
optional.orElseThrow(IllegalAccessError::new);

示例(2):通常,当值存在的情况下才消费该值是比较合理的做法。在流中,使用ifPresent方法接受一个函数可以实现该目的:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
//获取流中长度大于20的任意字符串,包装到一个Optional对象中
Optional<String> optional = stream.filter(s -> s.length() > 20).findAny();
//当值存在时,打印出字符串的长度,否则不执行任何操作
optional.ifPresent(s -> System.out.print("字符串" + s + "的长度为:" + s.length()));

ifPresent方法没有返回值,如果需要返回值,使用map方法:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
//获取流中长度大于20的任意字符串,包装到一个Optional对象中
Optional<String> optional = stream.filter(s -> s.length() > 20).findAny();
//当值存在时,返回包装了字符串长度的Optional对象,否则返回一个没有包装任何值的Optional对象。
Optional<Integer> integer = optional.map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return s.length();}
});
System.out.print(integer.orElse(-1));

2.2、不适合使用Optional值的方式:

(1)get方法可以在Optional值存在的情况下获得其中包装的元素,但值不存下时,却会抛出一个NoSuchElementException异常。

(2)isPresent方法可以判断某个Optional<T>对象是否具有值,但诸如下列的操作:

if (optionalValue.isPresent()) {
    optionalValue.get().someMethod();
}

并不比下列方式更容易处理:

if (value!=null){
    value.someMethod();
}

2.3、创建Optional值:

(1)static <T> Optional<T> of(T value):产生一个给定值的Optional对象,如果给定值为null,将抛出一个NullPointerException异常。

(2)static <T> Optional<T> ofNullable(T value):产生一个给定值的Optional对象,如果给定值为null,则产生一个不包含值的Optional。

(3)static <T> Optional<T> empty():产生一个空的(不包含值)的Optional对象。

3、收集流的结果:

(1)forEach方法访问旧式风格的迭代器:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
stream.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.print(s);}
});

(2)toArray方法接受一个数组构造器获得正确类型的数组:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
String[] array = stream.toArray(String[]::new);

(3)collect方法接受一个Collector接口的实例:

Stream<String> stream = Arrays.stream(new String[]{"Arrays", "stream"});
List<String> collect = stream.collect(Collectors.toList());