1,flatMap 详解,注意IDEA后面的类型提示
map-flatmap 操作
但是二段map-map操作效果
package model;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* 使用流,筛选,查找,过滤,切片,规约
*
* @since 2020年2月23日19:37:51
*/
public class Java8StreamTest {
public static void main(String[] args) {
// test001();
// test002();
// test003();
// test004();
// test005();
// test007();
// test008();
// test009();
// test011();
// test012();
// test013();
test014();
}
/**
* 外部迭代 和java8 的内部迭代
*
* @see java.util.stream.Stream#filter(Predicate)
* @see java.util.stream.Stream#collect(Collector)
*/
public static void test001() {
List<Dish> retList = new ArrayList<>();
List<Dish> dishs = new ArrayList<>();
dishs.add(new Dish().builder().id(1).name("apple").isVegetarian(true).build());
dishs.add(new Dish().builder().id(2).name("fish").isVegetarian(false).build());
for (Dish dish : dishs) {
if (dish.isVegetarian()) {
retList.add(dish);
}
}
System.out.println("外部迭代结果=" + JSON.toJSONString(retList));
//内部迭代
retList = dishs.stream()
.filter(Dish::isVegetarian)
.collect(Collectors.toList());
System.out.println("内部迭代结果=" + JSON.toJSONString(retList));
}
/**
* 筛选各异的元素
*
* @see Stream#distinct()
* @see Stream#forEach(Consumer)
* @see Stream#limit(long)
* @see Stream#skip(long)
* @see Stream#limit(long)
* @see Stream#map(Function)
*/
public static void test002() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 1, 2, 3);
list.stream().distinct().forEach(System.out::println);
System.out.println("=================");//去重
//筛选是偶数的
list.stream().filter(i -> i % 2 == 0).forEach(System.out::println);
System.out.println("=================");//取偶数的数字
//截断流
list.stream().limit(2).forEach(i -> System.out.println(i));//只取值前连个1,2
System.out.println("================");
//跳过流
list.stream().skip(2).forEach(i -> System.out.println(i));//跳过1,2
//映射
System.out.println("===================");
List<Dish> dishs2 = new ArrayList<>();
dishs2.add(new Dish().builder().id(1).name("apple").isVegetarian(true).build());
dishs2.add(new Dish().builder().id(2).name("fish").isVegetarian(false).build());
dishs2.stream().map(dish -> dish.getId() * 10).forEach(i -> System.out.println(i));
dishs2.stream().map(dish -> dish.getName().length()).forEach(i -> System.out.println(i));
}
/**
* 流的扁平化
*
* @see Stream#flatMap(Function)
* @see Stream#map(Function) 类似
* 区别:flatMap 不是各个元素映射分别映射自己的流,,而是所有的元素映射到一个新的流中
*/
public static void test003() {
String[] arr = {"hello", "world"};
Arrays.stream(arr)
.map(word -> word.split(""))
.map(array -> Arrays.stream(array))
//这一步把每一个数组有变成了流 Stream<Stream<String>>
.distinct()//去重字母
.forEach(w -> System.out.println(w));
//java.util.stream.ReferencePipeline$Head@768debd 最后循环出来的还是一个流
}
/**
* 应该是把数组合并为一个流
*/
public static void test004() {
String[] arr = {"hello", "world"};
Arrays.stream(arr)
.map(word -> word.split(""))
//将多个数组压回到一个数组中去
.flatMap(arrTmp -> Arrays.stream(arrTmp))
.distinct()//去重字母
.forEach(w -> System.out.println(w));
}
/**
* @see Stream#flatMap(Function) //Function<? super T, ? extends Stream<? extends R>
* 练习1
* 给定列表(1,2,3)(3,4)
* 返回数对[(1,3),(1,4),(2,3),(3,4),(3,3),(3,4)]
*/
public static void test005() {
//两层迭代
List<Integer> num1 = Arrays.asList(1, 2, 3);
List<Integer> num2 = Arrays.asList(3, 4);
//让stream1 的每个元素作为一个流映射stream2的每个元素
/**
* 流的二段操作哦
* 让数组变成流 Stream<Integer[]>
* 而不是
*/
List<int[]> pairsList = num1.stream()//num1 本来就是数组
.flatMap(i -> num2.stream()//Stream<Integer[]>
.map(j -> new int[]{i, j}))
.collect(Collectors.toList());
System.out.println(JSON.toJSONString(pairsList));
//[[1,3],[1,4],[2,3],[2,4],[3,3],[3,4]]
}
//匹配和查找
/**
* @see Stream#findAny()
* @see Stream#findFirst()
* @see Stream#allMatch(Predicate) a && b
* @see Stream#anyMatch(Predicate) a || b
* @see Stream#noneMatch(Predicate) !a && !b
*/
public static void test007() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
Optional<Integer> any = list.stream().findAny();
System.out.println(any.get());//1
Optional<Integer> first = list.stream().findFirst();
System.out.println(first.get());//1
boolean b = list.stream().allMatch(i -> i >= 5);
System.out.println(b);//false
boolean b1 = list.stream().anyMatch(i -> i >= 5);
System.out.println(b1);//true
boolean b2 = list.stream().noneMatch(i -> i >= 5);
System.out.println(b2);//false
list.stream().filter(i -> i > 2).forEach(i -> System.out.println(i));
}
/**
* 规约reduce 是一个终端操作,不能再继续流的操作了,到流尾了
* 规约操作就是将所有的元素结合起来得到一个值
*/
public static void test008() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
//BinaryOperator<T> accumulator 将两个值结合起来产生一个新的值
Integer reduce = list.stream().reduce(0, (a, b) -> a + b);
System.out.println(reduce);//15
//Integer::max 接收两个参数类似(x, y) -> x > y ? x : y
Optional<Integer> reduce1 = list.stream().reduce(Integer::max);
System.out.println(reduce1.get());//最大的元素是5
//等价lambda写法
Integer reduce2 = list.stream().reduce(0, (x, y) -> x > y ? x : y);
System.out.println(reduce2);//5
//终端操作count,计算元素的个数
long count = list.stream().count();//元素的个数5
System.out.println(count);
}
/**
* 最大,最小值,排序
*
* @see Stream#max(Comparator)
* @see Stream#min(Comparator)
* @see Stream#sorted(Comparator)
* //对象比较大小需要对象实现Comparator接口或者Comparable接口
*/
public static void test009() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5, 10, -1, -2);
Optional<Integer> max = list.stream().max(Integer::compareTo);
System.out.println(max.get());//10
Optional<Integer> min = list.stream().min(Integer::compareTo);
System.out.println(min.get());//-2
//public final class Integer extends Number implements Comparable<Integer>
//Integer 对象默认是实现了Comparable 接口的
Stream<Integer> sorted = list.stream().sorted(Integer::compareTo);
sorted.forEach(i -> System.out.println(i));//-2,-1,1,2,3,4,5,10
}
/**
* 数值流的一个注意
*/
public static void test011() {
List<Dish> dishs = new ArrayList<>();
dishs.add(new Dish().builder().calories(100).build());
dishs.add(new Dish().builder().calories(200).build());
dishs.add(new Dish().builder().calories(300).build());
Integer sums = dishs.stream().map(dish -> dish.getCalories())
//收集对象的calories 为一个流Strean<Integer>
.reduce(0, Integer::sum);//Stream 流没有sum方法
//这里有有个integer->int的拆箱成本
//原始流,推荐
int sum = dishs.stream().mapToInt(dish -> dish.getCalories()).sum();
System.out.println(sum);
}
/**
* 实战1
*
* @see Collectors#toList()
* @see Collectors#toSet()
* @see Collectors#toCollection(Supplier)
*/
public static void test012() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 1, 2, 3, 5, 10, -1, -2);
/**
* @see TreeSet
* //TreeSet<E> implements NavigableSet<E>,
* @see NavigableSet
* @see SortedSet
* //NavigableSet<E> extends SortedSet<E> {
*/
Collection<Integer> collect = list.stream().collect(Collectors.toCollection(TreeSet::new));
System.out.println(JSON.toJSONString(collect));//[-2,-1,1,2,3,4,5,10]
List<Integer> retList = list.stream().collect(Collectors.toList());
System.out.println(JSON.toJSONString(retList));//1,2,3,4,1,2,3,5,10,-1,-2]
Set<Integer> retSet = list.stream().collect(Collectors.toSet());
System.out.println(JSON.toJSONString(retSet));//[-1,1,-2,2,3,4,5,10]
String retStr = list.stream().map(i -> String.valueOf(i)).collect(Collectors.joining("|"));
System.out.println(retStr);//1|2|3|4|1|2|3|5|10|-1|-2
}
/**
* 原始流和对象流的相互转化
* @see Stream#mapToInt(ToIntFunction)
* @see IntStream#mapToObj(IntFunction)
*/
public static void test013() {
List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 2);
Stream<Integer> stream = list.stream();
//Stream->intStream
IntStream intStream = stream.mapToInt(i -> i);
System.out.println(intStream.sum());
//stream has already been operated upon or closed, 流不能二次操作
//intStream->Stream
// Stream<Integer> boxed = intStream.boxed();
// Integer sum = boxed.reduce(0, Integer::sum);
// System.out.println(sum);
//Stream->intStream->Stream
Optional<Integer> reduce = list.stream().mapToInt(i -> i).boxed().reduce(Integer::sum);
System.out.println(reduce.get());
}
/**
* 创建流
* @see Stream#of(Object)
* @see Stream#iterate(Object, UnaryOperator)
* @see Stream#empty()
* @see IntStream#range(int, int)
* @see IntStream#mapToObj(IntFunction)
*/
public static void test014() {
int[] a = {1, 2, 3};
IntStream stream = Arrays.stream(a);
/**
* @see IntStream#mapToObj(IntFunction)
*/
//IntStream->Stream
Stream<Integer> integerStream = stream.mapToObj(Integer::new);
IntStream range = IntStream.range(1, 1000);
Stream<Integer> integerStream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Object> empty = Stream.empty();
//无限流
Stream<Integer> limit = Stream.iterate(0, n -> n * 2).limit(100);
//文件操作返回流
/**
* @see java.nio.file.Files#lines(Path)
*
* try-with-resources 自动关闭流
*/
try (Stream<String> lines = Files.lines(Paths.get("D:/wn_fiction.sql"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* java 自动关闭IO 流语法
*/
public static void test015() {
File src = new File("D://a.txt");
File dest = new File("D://b.txt");
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest)) {
int read = fis.read();
fos.write(read);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}