Java-8-Stream接口
interface Stream
思维导图:
生成 Stream
Stream.of
静态方法(源码):
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
使用
public class M1 {
public static void main(String[] args) {
// /*************流的来源*************/
// 1、of方法
// of(T... values):返回含有多个T元素的Stream
// of(T t):返回含有一个T元素的Stream
Stream<String> stream1 = Stream.of(
"a","b","c","d","e"
);
stream1.forEach(System.out::println);
System.out.println("--------------------");
String[] strings = {"a","45","a"};
Stream<String> stream2 = Stream.of(strings);
stream2.forEach(System.out::println);
}
}
generate与iterate
源码:
public static<T> Stream<T> generate(Supplier<T> s) {
//...
}
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f){
//...
}
generate
public class M2 {
public static void main(String[] args) {
// generator方法,返回一个无限长度的Stream,其元素由Supplier接口的提供。
Stream<String> stream1 = Stream.generate(
() ->
"A"
);
// stream1.forEach(System.out::println);
Stream<Double> stream2 = Stream.generate(
()->
Math.random()
);
// stream2.forEach(System.out::println);
Stream<String> stream3 = Stream
.generate(() -> "love")
.limit(10);
stream3.forEach(System.out::println);
}
}
iterate
public class M3 {
public static void main(String[] args) {
// iterate方法,返回的也是一个无限长度的Stream,与generate方法不同的是,其是通过函数f迭代对给指定的元素种子而产生无限连续有序Stream,其中包含的元素可以认为是:seed,f(seed),f(f(seed))无限循环
Stream<Integer> stream1 = Stream.iterate(
1,integer -> integer + 2
);
stream1.limit(10).forEach(System.out::println);
System.out.println("---------------------");
//生成一个等差数列
Stream.iterate(0, n -> n + 3).limit(10). forEach(x -> System.out.print(x + " "));
}
}
合并Stream
源码:
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
//...
}
使用
public class M4 {
public static void main(String[] args) {
Stream<Integer> stream1 = Stream.of(
1,2,3,4,56
);
Stream<Integer> stream2 = Stream.of(
11,258,5689
);
Stream<Integer> stream3 = Stream.concat(stream1,stream2);
stream3.forEach(System.out::println);
System.out.println("---------");
// 合并多个流(Streams)
Stream<Integer> first = Stream.of(1, 2);
Stream<Integer> second = Stream.of(3,4);
Stream<Integer> third = Stream.of(5, 6);
Stream<Integer> fourth = Stream.of(7,8);
Stream<Integer> resultingStream = Stream.concat(first,Stream.concat(second,Stream.concat(third, fourth)));
resultingStream.forEach(System.out::println);
System.out.println("---------");
//合并stream并保留唯一性
Stream<Integer> firstStream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<Integer> secondStream = Stream.of(4, 5, 6, 7, 8, 9);
Stream<Integer> resultingStream_1 = Stream.concat(firstStream, secondStream)
.distinct();
resultingStream_1.forEach(System.out::println);
}
}
中间操作—filter
源码:
Stream<T> filter(Predicate<? super T> predicate);
使用
public class M1 {
public static void main(String[] args) {
//filter 对原Stream按照指定条件过滤,过滤出满足条件的元素。
List<Integer> integers = Create_Data.supply_Integers();
Predicate<Integer> predicate = integer ->
integer > 15;
// 通过传递predicate
integers.stream()
.filter(predicate)
.forEach(System.out::println);
System.out.println("---------------------------");
// 直接使用Lambda
integers.stream()
.filter(integer -> integer > 75 && integer < 85)
.forEach(System.out::println);
System.out.println("---------------------------");
List<Integer> list = Arrays.asList(3, 12, 23, 44, 20, 10, 17, 8);
System.out.println("---List with even Numbers---");
List<Integer> evenList = list.stream()
.filter(integer -> integer % 2 ==0)
.collect(Collectors.toList());
evenList.forEach(System.out::println);
System.out.println("\n---List with odd Numbers---");
List<Integer> oddList = list.stream().filter(i -> i%2 == 1)
.collect(Collectors.toList());
oddList.forEach(s -> System.out.print(s+" "));
}
}
中间操作—map
源码:
//Returns a stream consisting of the elements of this stream that match the given predicate.
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
map方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)
使用
public class M1 {
public static void main(String[] args) {
//map方法将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。
List<String> strings = Create_Data.supply_Strings(1,10);
System.out.println(strings);
System.out.println("");
strings.stream()
.map(s -> s.toLowerCase())
.forEach(System.out::println);
System.out.println("----------------");
List<Person> personList = Create_Data.supply_Persons();
List<Integer> ages = personList.stream()
.map(Person::getAge)
.collect(Collectors.toList());
ages.forEach(System.out::println);
System.out.println("---------------");
Stream<Integer> stream = Stream.of(1,2,4,5,6,8);
stream.map(integer -> integer * integer)
.forEach(System.out::println);
}
}
中间操作—mapToInt mapToLong mapToDouble
为了提高处理效率,官方已封装好了,三种变形:mapToDouble,mapToInt,mapToLong,将原Stream中的数据类型,转换为double,int或者long类型。
源码:
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
使用
public class M2 {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("ass,","jdjjfjf","145445");
Stream<Integer> stream2 = Stream.of(1,2556,4556,4556,4559,55);
// 打印每个字符串的长度
stream1.mapToInt(String::length).forEach(System.out::println);
System.out.println("-----------------------------------");
// 计算总和
int sum = stream2.mapToInt(Integer::intValue).sum();
System.out.println(sum);
}
}
中间操作—flatMap
源码:
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap
使用
public class M1 {
public static void main(String[] args) {
Stream<List<Integer>> inputStream = Stream.of(
Arrays.asList(1),
Arrays.asList(2, 3),
Arrays.asList(4, 5, 6)
);
// 把所有元素统一放入一个List里面
//
// inputStream.map(integers -> integers)
// .forEach(System.out::println);
//输出
//[1]
//[2, 3]
//[4, 5, 6]
//可以看到Map操作无法完成这个任务 它的输出是一个个的小流
System.out.println("------------------");
inputStream.flatMap(integers -> integers.stream())
.forEach(System.out::println);
System.out.println("-----------------------------------");
/**
* Stream flatMap with Array
* Here we will use flatMap with array. I am creating a two dimensional array with integer data. Finally we will find out even numbers.
* 1. Sample Array
* {{1,2},{3,4},{5,6}}
* 2. After flatMap(row -> Arrays.stream(row))
* {1,2,3,4,5,6}
* 3. After filter(num -> num%2 == 0)
* {2,4,6}
* Now find the example.
*/
Integer[][] data = {{1,2},{3,4},{5,6}};
Arrays.stream(data)
.flatMap(row -> Arrays.stream(row))
.filter(num -> num % 2 == 0)
.forEach(System.out::println);
System.out.println("-----------------------------------");
List<List<Integer>> out = new ArrayList<>();
List<Integer> inner1 = Create_Data.supply_Integers();
List<Integer> inner2 = Create_Data.supply_Integers();
List<Integer> inner3 = Create_Data.supply_Integers();
out.add(inner1);out.add(inner2);out.add(inner3);
out.stream()
.flatMap(r -> r.stream())
.forEach(System.out::println);
System.out.println("-----------------------------------");
List<String> list1 = Arrays.asList("AAA","BBB");
List<String> list2 = Arrays.asList("CCC","DDD");
Stream.of(list1,list2)
.flatMap(list -> list.stream())
.forEach(System.out::println);
}
}
中间操作—flatMapToInt flatMapToLong flatMapToDouble
flatMap也提供了针对特定类型的映射操作:flatMapToDouble(Function<? super T,? extends DoubleStream> mapper),flatMapToInt(Function<? super T,? extends IntStream> mapper),flatMapToLong(Function<? super T,? extends LongStream> 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);
使用
public class M2 {
public static void main(String[] args) {
double[][] data = {{1.5,2.4},{3.2,4.4},{5.2,6.8}};
Arrays.stream(data)
.map( doubles -> doubles)
.forEach(System.out::println);
//[D@7cca494b
//[D@7ba4f24f
//[D@3b9a45b3
System.out.println("--------------------------------");
Arrays.stream(data)
.flatMapToDouble(r -> Arrays.stream(r))
.forEach(System.out::println);
//1.5
//2.4
//3.2
//4.4
//5.2
//6.8
System.out.println("--------------------------------");
int[][] data1 = {{1,2},{3,4},{5,6}};
IntStream intStream = Arrays.stream(data1)
.flatMapToInt(row -> Arrays.stream(row));
System.out.println(intStream.sum());
}
}
中间操作—distinct
源码:
Stream<T> distinct();
distinct()使用hashCode()和equals()方法来获取不同的元素。因此,我们的类必须实现hashCode()和equals()方法。如果distinct()正在处理有序流,那么对于重复元素,将保留以遭遇顺序首先出现的元素,并且以这种方式选择不同元素是稳定的。在无序流的情况下,不同元素的选择不一定是稳定的,是可以改变的。distinct()执行有状态的中间操作。在有序流的并行流的情况下,保持distinct()的稳定性是需要很高的代价的,因为它需要大量的缓冲开销。如果我们不需要保持遭遇顺序的一致性,那么我们应该可以使用通过BaseStream.unordered()方法实现的无序流
使用
public class M1 {
public static void main(String[] args) {
List<String> list = Arrays.asList("AA", "BB", "CC", "BB", "CC", "AA", "AA");
list.stream()
.distinct()
.forEach(System.out::println);
}
}
public class Book {
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
final Book book = (Book) obj;
if (this == book) {
return true;
} else {
return (this.name.equals(book.name) && this.price == book.price);
}
}
@Override
public int hashCode() {
int hashno = 7;
hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
return hashno;
}
}
public class DistinctByProperty {
//distinct() does not provide distinct elements by property or key. It works on the basis of hashCode() and equals(). If we want distinct element by a property or key, we can achieve it by a work around code. Find the code snippet.
public static void main(String[] args) {
List<Book> list = new ArrayList<>();
{
list.add(new Book("Core Java", 200));
list.add(new Book("Core Java", 300));
list.add(new Book("Learning Freemarker", 150));
list.add(new Book("Spring MVC", 200));
list.add(new Book("Hibernate", 300));
}
list.stream().filter(distinctByKey(b -> b.getName()))
.forEach(b -> System.out.println(b.getName()+ "," + b.getPrice()));
}
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
中间操作—sorted
源码:
/**
* Returns a stream consisting of the elements of this stream, sorted
* according to natural order. If the elements of this stream are not
* {@code Comparable}, a {@code java.lang.ClassCastException} may be thrown
* when the terminal operation is executed.
*/
//它使用自然顺序对流的元素进行排序。元素类必须实现Comparable接口。
Stream<T> sorted();
//Returns a stream consisting of the elements of this stream, sorted
//according to the provided {@code Comparator}.
Stream<T> sorted(Comparator<? super T> comparator);
使用
public class M1 {
public static void main(String[] args) {
List<Integer> integerList = Create_Data.supply_Integers();
System.out.println(integerList);
System.out.println("------------------");
List<Integer> l1 = integerList.stream().sorted().collect(Collectors.toList());
System.out.println(l1);
System.out.println("------------------");
//自然序逆序元素,使用Comparator 提供的reverseOrder() 方法
List<Integer> l2 = integerList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println(l2);
System.out.println("------------------");
List<Student> students = Student.supply_S();
List<Student> list = students.stream()
.sorted(Comparator.comparing(Student::getAge))
.collect(Collectors.toList());
System.out.println(list);
}
}
public class Student {
private static Random random = new Random();
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static List<Student> supply_S(){
List<Student> list = new ArrayList<>();
for (int i = 0; i < 12; i++) {
list.add(new Student(i+"",random.nextInt(100)));
}
return list;
}
}
中间操作—peek
源码:
// * @apiNote This method exists mainly to support debugging, where you want
// * to see the elements as they flow past a certain point in a pipeline:
// * <pre>{@code
// * Stream.of("one", "two", "three", "four")
// * .filter(e -> e.length() > 3)
// * .peek(e -> System.out.println("Filtered value: " + e))
// * .map(String::toUpperCase)
// * .peek(e -> System.out.println("Mapped value: " + e))
// * .collect(Collectors.toList());
Stream<T> peek(Consumer<? super T> action);
使用
public class M1 {
public static void main(String[] args) {
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
System.out.println("--------------------");
List<Integer> l1 = Create_Data.supply_Integers();
l1.stream()
.peek(integer -> System.out.println(integer))
.limit(5)
.forEach(System.out::println);
System.out.println("--------------------");
List<Integer> list = Arrays.asList(10,11,12);
list.stream().peek(i->System.out.println(i*i)).collect(Collectors.toList());
}
}
中间操作—limit
源码:
Stream<T> limit(long maxSize);
使用
public class M1 {
public static void main(String[] args) {
List<String> list = Arrays.asList("AA","BB","CC","DD","EE");
list.stream().limit(3).forEach(s->System.out.println(s));
System.out.println("-------------");
List<Integer> l2 = Create_Data.supply_Integers();
l2.stream()
.limit(5)
.forEach(System.out::println);
}
}
中间操作—skip
源码:
Stream<T> skip(long n);
使用
public class M1 {
public static void main(String[] args) {
List<String> list = Arrays.asList("AA","BB","CC","DD");
//跳过前两个
list.stream().skip(2).forEach(s->System.out.println(s));
}
}
终端操作—forEach
源码:
void forEach(Consumer<? super T> action);
使用
public class M1 {
public static void main(String[] args) {
List<Integer> integers = Create_Data.supply_Integers();
integers.stream()
.forEach(integer -> System.out.println(integer + "'号"));
}
}
终端操作—forEachOrdered
源码:
void forEachOrdered(Consumer<? super T> action);
使用
public class M2 {
public static void main(String[] args) {
Stream.of("AAA,","BBB,","CCC,","DDD,").parallel().forEach(System.out::print);
System.out.println("\n______________________________________________");
Stream.of("AAA,","BBB,","CCC,","DDD").parallel().forEachOrdered(System.out::print);
System.out.println("\n______________________________________________");
Stream.of("DDD,","AAA,","BBB,","CCC").parallel().forEachOrdered(System.out::print);
}
}
对于forEachOrdeed ,当stream 为parallel的时候,尽管是多个线程,并行处理的。但是还是会按照他source原有的顺序输出,,底层是通过happensbefore原则保证了它的内存可见性
终端操作—toArray
源码:
Object[] toArray();
// * The generator function takes an integer, which is the size of the
// * desired array, and produces an array of the desired size. This can be
// * concisely expressed with an array constructor reference:
<A> A[] toArray(IntFunction<A[]> generator);
使用
public class M1 {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of(
"a","dkkdk","1241","kdkdi","lpp"
);
Object[] objects1 = stream1.toArray();
for(Object o:objects1){
System.out.println(o);
}
System.out.println("--------------------");
List<Integer> integers = Create_Data.supply_Integers();
Object[] objects2 = integers.stream()
.toArray();
for(Object o:objects2){
System.out.println(o);
}
System.out.println("--------------------");
Object[] ob = Stream.of("A","B","C","D").toArray();
for (Object o : ob) {
System.out.println(o.toString());
}
}
}
public class M2 {
public static void main(String[] args) {
List<Person> people = Person.supply_S();
Person[] peoplearray = people.stream()
.filter(person -> person.getGender().equals("male"))
.toArray(Person[]::new);
for (Person person:peoplearray){
System.out.println(person);
}
System.out.println("------------------");
Integer[] integers = Stream.of(1, 2, 3, 4, 5).toArray(Integer[]::new);
}
}
终端操作—reduce
源码:
// * @apiNote Sum, min, max, average, and string concatenation are all special
// * cases of reduction. Summing a stream of numbers can be expressed as:
// *
// * <pre>{@code
// * Integer sum = integers.reduce(0, (a, b) -> a+b);
// * }</pre>
// *
// * or:
// *
// * <pre>{@code
// * Integer sum = integers.reduce(0, Integer::sum);
// * }</pre
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);
先看第一个
官方API文档有这样一段:
U result = identity;
for (T element : this stream)
result = accumulator.apply(result, element)
return result;
这就是一个累加器概念的体现:
一个reduce操作(也称为折叠)接受一系列的输入元素,并通过重复应用操作将它们组合成一个简单的结果
public class M1 {
// * <pre>{@code
// * U result = identity;
// * for (T element : this stream)
// * result = accumulator.apply(result, element)
// * return result;
// * }</pre>
public static void main(String[] args) {
List<Integer> l1 = Arrays.asList(1,2,3,4,5);
//计算1,2,3,4,5 的和,并且初始值为3
//也就是计算3+1+2+3+4+5
System.out.println(
l1.stream().reduce(
3,(i1,i2)->i1+i2
)
);
System.out.println("------------------------");
// 拆开分解
BinaryOperator<Integer> f1 = (x,y)->x+y;
Integer identity = 3;
Integer result = identity;
for (Integer integer:l1){
result = f1.apply(result,integer);
}
System.out.println(result);
//其实两种方式背后的思维方式是一样的
//那就是
//结果重新作为一个参数,不断地参与到运算之中,直到最后结束
//只要能够理解了累计运算的概念
//就可以完全理解Stream 中reduce方法
//他就是一个不断累计运算的过程
System.out.println("------------------------");
//计算 1*1*2*3*4*5 = 120
System.out.println(
l1.stream()
.reduce(1,(x,y)->x*y)
);
}
}
第二个
因为存在stream为空的情况,所以第二种实现并不直接方法计算的结果,而是将计算结果用Optional来包装,我们可以通过它的get方法获得一个Integer类型的结果,而Integer允许null。第一种实现因为允许指定初始值,因此即使stream为空,也不会出现返回结果为null的情况,当stream为空,reduce为直接把初始值返回
使用
public class M2 {
// This is equivalent to:
// * boolean foundAny = false;
// * T result = null;
// * for (T element : this stream) {
// * if (!foundAny) {
// * foundAny = true;
// * result = element;
// * }
// * else
// * result = accumulator.apply(result, element);
// * }
// * return foundAny ? Optional.of(result) : Optional.empty();
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
System.out.println(l1);
System.out.println("----------------------");
System.out.println(
l1.stream()
.reduce((x,y) -> x + y)
.get()
);
}
}
第三种
- 与两个参数的reduce不同的地方在于类型
- 双参数的返回类型为T Stream类型为T
- 三参数的返回类型为U Stream类型为T 有了更大的发挥空间 T可能为U 也可能不是U
第三个参数用于在并行计算下 合并各个线程的计算结果
使用
public class M3 {
public static void main(String[] args) {
ArrayList<Integer> newList = new ArrayList<>();
ArrayList<Integer> accResult_ = Stream.of(2, 3, 4)
.reduce(newList ,
(acc, item) -> {
acc.add(item);
System.out.println("item: " + item);
System.out.println("acc+ : " + acc);
System.out.println("BiFunction");
return acc;
}, (acc, item) -> null);
System.out.println("accResult_: " + accResult_);
//item: 2
//acc+ : [2]
//BiFunction
//item: 3
//acc+ : [2, 3]
//BiFunction
//item: 4
//acc+ : [2, 3, 4]
//BiFunction
//accResult_: [2, 3, 4]
}
}
第三个参数定义的规则并没有执行。这是因为reduce的第三个参数是在使parallelStream的reduce操作时,合并各个流结果的,本例中使用的是stream,所以第三个参数是不起作用的。上述示例,提供一个只有一个元素1的arrayList,通过累加器迭代,将stream中的数据添加到arrayList中
终端操作—collect
源码:
// This
// * produces a result equivalent to:
// * <pre>{@code
// * R result = supplier.get();
// * for (T element : this stream)
// * accumulator.accept(result, element);
// * return result;
// * }</pre>
// * For example, the following will accumulate strings into an {@code ArrayList}:
// * <pre>{@code
// * List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add,
// * ArrayList::addAll);
// * }</pre>
// *
// * <p>The following will take a stream of strings and concatenates them into a
// * single string:
// * <pre>{@code
// * String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,
// * StringBuilder::append)
// * .toString();
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
// * @apiNote
// * The following will accumulate strings into an ArrayList:
// * <pre>{@code
// * List<String> asList = stringStream.collect(Collectors.toList());
// * }</pre>
// *
// * <p>The following will classify {@code Person} objects by city:
// * <pre>{@code
// * Map<String, List<Person>> peopleByCity
// * = personStream.collect(Collectors.groupingBy(Person::getCity));
// * }</pre>
// *
// * <p>The following will classify {@code Person} objects by state and city,
// * cascading two {@code Collector}s together:
// * <pre>{@code
// * Map<String, Map<String, List<Person>>> peopleByStateAndCity
// * = personStream.collect(Collectors.groupingBy(Person::getState,
// * Collectors.groupingBy(Person::getCity)));
// * }</pre>
<R, A> R collect(Collector<? super T, A, R> collector);
第一个
supplier:一个能创造目标类型实例的方法。accumulator:一个将当元素添加到目标中的方法。combiner:一个将中间状态的多个结果整合到一起的方法(并发的时候会用到)
使用
public class M1 {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("asas","kdkkd","pp[p[","12121","O");
// List<String> l1 = stream1.collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
// System.out.println(l1);
System.out.println("--------------------");
String concat1 = stream1.collect(StringBuilder::new, StringBuilder::append,
StringBuilder::append)
.toString();
System.out.println(concat1);
System.out.println("--------------------------------");
List<Integer> l2 = Create_Data.supply_Integers();
System.out.println(l2);
System.out.println("--------------------------------");
// 找出偶数 放入新的集合
List<Integer> res1 = l2.stream()
.filter(integer -> integer % 2 == 0)
.collect(
()->new ArrayList<>(),
(list,item)->list.add(item),
(x,y)->x.addAll(y)
);
System.out.println(res1);
System.out.println("--------------------------------");
/* 或者使用方法引用 */
List<Integer> res2 =l2.stream()
.filter(integer -> integer % 2 == 0)
.collect(
ArrayList::new, List::add, List::addAll
);
System.out.println(res2);
}
}
上面例子:
-
第一个函数生成一个新的ArrayList(最后返回的也是这个)
-
第二个函数的第一个参数是前面生成的ArrayList对象,第二个参数是stream中包含的元素,函数体就是把stream中的元素加入ArrayList对象中。第二个方法被反复调用直到原stream的元素被消费完毕
第二个
使用
public class M2 {
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
List<Integer> res1 = l1.stream()
.filter(integer -> integer>55)
.collect(Collectors.toList());
System.out.println(res1);
/*输出*/
// [79, 89, 65, 98, 74, 90, 75, 61]
}
}
终端操作—min
源码:
Optional<T> min(Comparator<? super T> comparator);
使用
public class M1 {
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
System.out.println(l1);
System.out.println("------------------------------");
System.out.println(
l1.stream()
.min(Integer::compareTo).get()
);
System.out.println("------------------------------");
System.out.println(
l1.stream()
.min(Comparator.comparing(Function.identity())).get()
);
List<String> strings1 = Create_Data.supply_Strings(10,5);
System.out.println("------------------------------");
System.out.println(strings1);
System.out.println("------------------------------");
System.out.println(
strings1.stream()
.min(Comparator.comparing(Function.identity())).get()
);
System.out.println("------------------------------");
List<Person> personList = Person.supply_S();
System.out.println(personList);
System.out.println("------------------------------");
System.out.println(
personList.stream()
.min(Comparator.comparing(Person::getAge)).get()
);
}
}
终端操作—max
源码:
Optional<T> max(Comparator<? super T> comparator);
使用参照 min
终端操作—count
源码:
// * This is a special case of
// * a <a href="package-summary.html#Reduction">reduction</a> and is
// * equivalent to:
// * <pre>{@code
// * return mapToLong(e -> 1L).sum();
// * }</pre>
long count();
count方法用于统计Stream流中元素的个数,这是个终结方法,使用后无法使用其他Stream流
使用
public class M1 {
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
System.out.println(
l1.stream()
.count()
);
}
}
终端操作—anyMatch allMatch noneMatch
源码:
boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
使用
public class M1 {
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
// 是否有大于55的数字
System.out.println(
l1.stream()
.anyMatch(integer -> integer> 55)
);
// 是否全部都是大于33的数字
System.out.println(
l1.stream()
.allMatch(integer -> integer>33)
);
// 是否全部数字都不大于200
System.out.println(
l1.stream()
.noneMatch(integer -> integer>200)
);
}
}
终端操作—findFirst findAny
源码:
Optional<T> findFirst();
Optional<T> findAny();
使用
public class M1 {
public static void main(String[] args) {
List<Integer> l1 = Create_Data.supply_Integers();
System.out.println(l1);
System.out.println("-------------------------");
System.out.println(
l1.stream()
.findFirst()
.get()
);
System.out.println("-------------------------");
System.out.println(
l1.stream()
.findAny()
.get()
);
}
}