JAVA8Stream接⼝流式⽅法map操作filter操作以及flatMap操
作
关于stream 流式操作,在rt.jar 包⾥⾯,ReferencePipeline管道⽅式操作数据 下⾯集成所有操作⽅法,利⽤这些流,处理⼤数据的⽅式,效率提升明显,并且很多语⾔都⽀持这种操作,相当于统⼀了这种编程⽅式。
我们先来看看这三个操作过滤的是什么数据,
过滤之后仍然可以循环数据
list.stream().filter(smap -> null != ("ip") && !"".("ip"))).forEach(imp -> {
listipzone.add(wry.("ip").toString()));
});
1,filter操作,我们先看⽅法的定义
源码如下Stream<T> filter(Predicate<? super T> predicate); ⼀个单纯的过滤操作直接返回传⼊类型
String[] dd = { "a", "b", "c" };
Stream<String> stream = Arrays.stream(dd);
stream.filter(str -> str.equals("a")).forEach(System.out::println);//返回字符串为a的值
2.map操作,先看⽅法定义
源码如下 <R> Stream<R> map(Function<? super T, ? extends R> mapper);
这个⽅法传⼊⼀个Function的函数式接⼝,这个接⼝,接收⼀个泛型T,返回泛型R,map函数的定义,返回的流,表⽰的泛型是R对象,这个表⽰,调⽤这个函数后,可以改变返回的类型
public static void main(String[] args) {
Integer[] dd = { 1, 2, 3 };
Stream<Integer> stream = Arrays.stream(dd);
stream.map(str -> String(str)).forEach(str -> {
System.out.println(str);// 1 ,2 ,3
System.out.Class());// class java.lang.String
});
List<Emp> list = Arrays.asList(new Emp("a"), new Emp("b"), new Emp("c"));
list.stream().map(emp -> Name()).forEach(str -> {
System.out.println(str);
});
}
public static class Emp {
private String name;
public Emp() {
super();
}
public Emp(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
可以看到,我们把Integer,变成了String输出,把Emp对象⾥的name字符串,单独输出;现在,我们只看到了⼀个forEach的终端操作,后⾯,我们会看到,更多的终端操作,把map操作后,改变的对象类型,返回各种类型的集合,或者对数字类型的,返回求和,最⼤,最⼩等的操作;
3.flatMap操作,我们还是先看接⼝定义 包含前⾯两种过滤类型
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
这个接⼝,跟map⼀样,接收⼀个Fucntion的函数式接⼝,不同的是,Function接收的泛型参数,第⼆个参数是⼀个Stream流;⽅法,返回的也是泛型R,具体的作⽤是把两个流,变成⼀个流返回,下⾯,我们看⼀个案例,来详细解答,怎么把两个流的内容,变成⼀个流的内容
public static void main(String[] args) {
String[] strs = { "aaa", "bbb", "ccc" };
Arrays.stream(strs).map(str -> str.split("")).forEach(System.out::println);// Ljava.lang.String;@53d8d10a
Arrays.stream(strs).map(str -> str.split("")).flatMap(Arrays::stream).forEach(System.out::println);// aaabbbccc
Arrays.stream(strs).map(str -> str.split("")).flatMap(str -> Arrays.stream(str)).forEach(System.out::println);// aaabbbccc
}
⾸先,第⼆段代码,才输出的具体的字符串;
第⼀段输出代码⾥,我们先看map操作,通过上⾯对map的介绍,我们可以看到,map可以改变返回的Stream的泛型,str.split(""),根据
空字符串分隔,返回的类型是⼀个数组,返回的流也是Stream<String[]>,⽽不是Stream<String>;在第⼆段代码中,数组的流,经过
map操作,返回Stream<String[]>后,再经过flatMap,把数组通过Arrays.stream变成⼀个新的流,再返回到原来的流⾥;这样,两个流
就合并成⼀个流;第三段代码,是第⼆段代码的,另⼀种写法;
PS 简单操作⽰例 1filter 过滤,2 map可以返回其它类型,3 flatMap合并两个流数据
String[] includes=new String[10];
List<String> maplist = includeList.stream().map(s -> s.equals("a6")?"a6L":s).List());
List<String> filterlist = includeList.stream().filter(s -> s.equals("a6")).List());
includeList.stream().map(s -> s.equals("a6")?"a6L":s).forEach(System.out::println);//直接操作⾥⾯的数据,改变逻辑后可以返回list等
filterlist.forEach(System.out::println);// 只打印a6过滤的数据
maplist.forEach(System.out::println);
4 构造流的⼏种常见⽅法
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. Collections
List<String> list = Arrays.asList(strArray);
stream = list.stream();
// map对象进⾏排序对⽐,最主要还是要把数字转化为 Integer类型去⽐较,否则只是字符串⽐较,⽆意义,封装成⼀个可⽐较的数据类型,转化字符串为数字类型就 model.put("data", listMap.stream()
.sorted((a, b) -> Integer.("count").toString())pareTo(Integer.("count").toString())))
5 流转换为其它数据结构
// 1. Array
String[] strArray1 = Array(String[]::new);
// 2. Collection
List<String> list1 = List());
List<String> list2 = Collection(ArrayList::new));
Set set1 = Set());
Stack stack1 = Collection(Stack::new));
// 3. String
String str = llect(Collectors.joining()).toString();
//分组构造Map
Map<Integer, String> factoryMap = factoryConfigDOS.stream().collect( upingBy(AgencyDailySalaryFactoryConfigDO::getFenceId, Collectors.mappin
//Map转化函数表达式转成MAP,key1和key2重复就覆盖不然会报错
Map nameMap = incumbentExcelInfoList.stream().Map(info -> IdCard(), info -> Name(),(key1,key2)->key2));
⼀个 Stream 只可以使⽤⼀次
很多API都有这种⽅式的操作,对后期⼤数据或者其它语⾔兼容,解决跨语⾔的问题,也提交了效率,⽇后要以这种⽅式处理数据,
6 流的操作
接下来,当把⼀个数据结构包装成 Stream 后,就要开始对⾥⾯的元素进⾏各类操作了。常见的操作可以归类如下。
Intermediate:(中间)
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
Terminal:(终端)
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
Short-circuiting:(短路)
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limi
limit/skip
limit 返回 Stream 的前⾯ n 个元素;skip 则是扔掉前 n 个元素(它是由⼀个叫 subStream 的⽅法改名⽽来)。
List<String> personList2 = persons.stream().
map(Person::getName).limit(10).skip(3).List());
System.out.println(personList2);
所有 Stream 的操作必须以 lambda 表达式为参数
merge为Map接⼝新增的默认⽅法
// k-8值存在为value8->执⾏merge函数->直接返回"NewMerge8"->newValue为"NewMerge8"
// 执⾏put->所以这⾥输出"NewMerge8"
<(8, "merge", (value, newValue) -> "NewMerge8");
System.out.(8));
// 合并⽅式
String newValue2 = (9, "concat", (value, newValue) -> at(newValue));
// 解释:从字符串序列中过滤出以字符a开头的字符串并迭代打印输出
stringList.stream().filter((s) -> s.startsWith("a")).forEach(System.out::println);
组合查询 主要是peek 监视消费后执⾏的动作
List<Integer> nums = wArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
System.out.println(“sum is:”+nums.stream().filter(num -> num != null).
distinct().mapToInt(num -> num * 2).
peek(System.out::println).skip(2).limit(4).sum());
filter过滤对象数组Integer类型的List,获取其对应的Stream对象,然后进⾏过滤掉null,再去重,再每个元素乘以2,再每个元素被消费的时候打印⾃⾝,在跳过前两个元素,最后去前四个元素进⾏加和运算
7 数据并⾏化操作
Stream 的并⾏化也是 Java 8 的⼀⼤亮点。数据并⾏化是指将数据分成块,为每块数据分配单独的处理单元。这样可以充分利⽤多核 CPU 的优势。
并⾏化操作流只需改变⼀个⽅法调⽤。如果已经有⼀个 Stream 对象,调⽤它的 parallel() ⽅法就能让其拥有并⾏操作的能⼒。如果想从⼀个集合类创建⼀个流,调⽤ parallelStream() 就能⽴即获得⼀个拥有并⾏能⼒的流。
int sumSize = Stream.of("Apple", "Banana", "Orange", "Pear") .parallel() .map(s -> s.length()) .reduce(Integer::sum) .get(); assertEquals(sumSize, 21);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论