/**
* .map .collect(Collectors.toList)
*/
private static void method2(){
List<MyPerson> collect = Stream.of("1:name1", "2:name2").map(new Function<String, MyPerson>() {
@Override
public MyPerson apply(String s) {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}).collect(Collectors.toList());
System.out.println(collect.toString());
}
实际输出
这里我重写了MyPerson 类的toString 等方法
[MyPerson{id=1, name='name1'}, MyPerson{id=2, name='name2'}]
Stream.of(“1:name1”, “2:name2”) 译为将多个of 中的元素转为Stream 中的集合元素
.map 这里作用为将 Function中的第一个泛型元素也就是Stream 中的元素泛型,转为 MyPerson 对象,这里 MyPerson 为我自己定义的对象,只有id 和 name 两个属性。 重写的方法 apply 为对每个Stream 中的String 元素的操作,并且通过这个方法将返回预期的 MyPerson 对象,即 .map 作用为将Stream 中的每一个元素转为另一种元素的映射操作,实际就是一个转换的中间方法。
.collect 说明接下来要使用集合类操作 即使用了 Collectors.toList() 方法,该方法最终会将Stream 中的元素输出为 List 类型的对象
/**
* .map .collect(Collectors.toMap())
*/
private static void method3(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(new Function<String, MyPerson>() {
@Override
public MyPerson apply(String s) {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}).collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}
实际输出
{1=MyPerson{id=1, name='name1'}, 2=MyPerson{id=2, name='name2'}}
MyPerson{id=1, name='name1'}
MyPerson{id=2, name='name2'}
即 .collect(Collectors.toMap(MyPerson::getId, Function.identity()));
意义为使用集合方法中的toMap() 方法,toMap中,第一个参数为作为Map 的key, Function.identity() 对应key 的值为 当前元素自己,结果如上展示
上述案例也可以写为:
map 中 可以直接使用lambda 表达式给出返回结果 s 即Stream 中的每个元素
/**
* .map .collect(Collectors.toMap()) lambda
*/
private static void method4(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(s -> {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}).collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}
上述案例 可以进一步简写为:
即 .map 中可以直接使用引用某一已经存在的方法来获取结果 MyPerson::transEntity 见末尾MyPerson 中定义的方法
/**
* .map .collect(Collectors.toMap()) lambda level up MapTrans
*/
private static void method5(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(MyPerson::transEntity)
.collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}
其中 Function.identity() 也可以如下写法 s -> s 也表示直接获取当前对象作为 Map的值
/**
* .map .collect(Collectors.toMap()) lambda level up MapTrans
*/
private static void method6(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(MyPerson::transEntity)
.collect(Collectors.toMap(MyPerson::getId, s -> s));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}
private static void lambdaTestToList(){
String m = "a,b,c,d,d,d,d,d";
Stream.of("a", "aa", "aaa", "b", "bb", "bbb").collect(Collectors.toList()).forEach((item) -> {
System.out.println(item);
});
System.out.println("*******************");
Stream.of(m.split(",")).collect(Collectors.toList()).forEach((item) -> {
System.out.println(item);
});
System.out.println("*******************");
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
List<MyPerson> list = new ArrayList<>();
list.add(myPerson);
list.add(myPerson2);
list.add(myPerson1);
List<List<MyPerson>> collect = Stream.of(list).collect(Collectors.toList());
List<Object> collect1 = Stream.of(list.toArray()).collect(Collectors.toList());
System.out.println("*******************");
collect.stream().forEach(item -> {
System.out.println(item.toString());
});
System.out.println("*******************");
collect1.stream().forEach(item -> {
System.out.println(item);
});
}
输出结果:
a
aa
aaa
b
bb
bbb
*******************
a
b
c
d
d
d
d
d
*******************
*******************
[MyPerson{id=1, name='545'}, MyPerson{id=3, name='445'}, MyPerson{id=2, name='333'}]
*******************
MyPerson{id=1, name='545'}
MyPerson{id=3, name='445'}
MyPerson{id=2, name='333'}
Process finished with exit code 0
可以看的出常见的 逗号拼接方式的字符串也可以通过 toList 快速转为我们常用的 list 形式并做一定的操作
上述案例中直接list 转 set 做去重和类型转换十分快捷
// 定义
private static String arrayStr = "1,2,3,4, 5,6,7";
private static String arrayStrEN = "a,b,c,d,d,d,f";
private static List<MyPerson> listObject = new ArrayList<>();
private static List<JSONObject> listJsonObject = new ArrayList<>();
static {
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
MyPerson myPerson3 = new MyPerson(2, "333");
listObject.add(myPerson);
listObject.add(myPerson1);
listObject.add(myPerson2);
listObject.add(myPerson3);
JSONObject object = new JSONObject();
object.put("dep", 124);
object.put("userId", "14");
object.put("names", "aka");
JSONObject object1 = new JSONObject();
object1.put("dep", 124);
object1.put("userId", "14");
object1.put("names", "aka1");
JSONObject object2 = new JSONObject();
object2.put("dep", 125);
object2.put("userId", "15");
object2.put("names", "aka2");
JSONObject object3 = new JSONObject();
object3.put("dep", 125);
object3.put("userId", "15");
object3.put("names", "aka3");
JSONObject object4 = new JSONObject();
object4.put("dep", 136);
object4.put("userId", "14");
object4.put("names", "aka4");
listJsonObject.add(object);
listJsonObject.add(object1);
listJsonObject.add(object2);
listJsonObject.add(object3);
listJsonObject.add(object4);
}
public static void lambdaToSet(){
Stream.of(arrayStr.split(",")).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item.trim());
});
System.out.println("---------------");
Stream.of(arrayStrEN.split(",")).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item.trim());
});
System.out.println("-----------");
Stream.of(listObject.toArray()).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item);
});
}
输出结果:
1
2
3
4
5
6
7
---------------
a
b
c
d
f
-----------
MyPerson{id=2, name='333'}
MyPerson{id=3, name='445'}
MyPerson{id=1, name='545'}
// 定义
private static List<MyPerson> listObject = new ArrayList<>();
private static List<JSONObject> listJsonObject = new ArrayList<>();
static {
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
MyPerson myPerson3 = new MyPerson(2, "333");
listObject.add(myPerson);
listObject.add(myPerson1);
listObject.add(myPerson2);
listObject.add(myPerson3);
JSONObject object = new JSONObject();
object.put("dep", 124);
object.put("userId", "14");
object.put("names", "aka");
JSONObject object1 = new JSONObject();
object1.put("dep", 124);
object1.put("userId", "14");
object1.put("names", "aka1");
JSONObject object2 = new JSONObject();
object2.put("dep", 125);
object2.put("userId", "15");
object2.put("names", "aka2");
JSONObject object3 = new JSONObject();
object3.put("dep", 125);
object3.put("userId", "15");
object3.put("names", "aka3");
JSONObject object4 = new JSONObject();
object4.put("dep", 136);
object4.put("userId", "14");
object4.put("names", "aka4");
listJsonObject.add(object);
listJsonObject.add(object1);
listJsonObject.add(object2);
listJsonObject.add(object3);
listJsonObject.add(object4);
}
public static void lambdaGroupBy(){
System.out.println("--------------按某一属性分组 返回key Object 的Map");
Map<Integer, List<MyPerson>> collect = listObject.stream().collect(Collectors.groupingBy(MyPerson::getId));
System.out.println(collect.toString());
System.out.println("--------------按某些属性的组合作为键 返回key Object的Map");
Map<String, List<MyPerson>> collect1 = listObject.stream().collect(Collectors.groupingBy(myPerson -> myPerson.getId() + myPerson.getName() + ""));
System.out.println(collect1.toString());
System.out.println("--------------按JSON 的某些属性组合作为键 返回key Object的Map");
Map<String, List<JSONObject>> collect2 = listJsonObject.stream().collect(Collectors.groupingBy(item -> item.get("dep") + item.getString("userId")));
System.out.println(collect2);
System.out.println("--------------按某一属性分组后, 获取当前分组后Map的size 可用于统计");
Integer collect3 = listObject.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(MyPerson::getId), Map::size));
System.out.println(collect3);
}
main 中运行 lambdaGroupBy
输出结果如下:
--------------按某一属性分组 返回key Object 的Map
{1=[MyPerson{id=1, name='545'}], 2=[MyPerson{id=2, name='333'}, MyPerson{id=2, name='333'}], 3=[MyPerson{id=3, name='445'}]}
--------------按某些属性的组合作为键 返回key Object的Map
{1545=[MyPerson{id=1, name='545'}], 3445=[MyPerson{id=3, name='445'}], 2333=[MyPerson{id=2, name='333'}, MyPerson{id=2, name='333'}]}
--------------按JSON 的某些属性组合作为键 返回key Object的Map
{12515=[{"names":"aka2","userId":"15","dep":125}, {"names":"aka3","userId":"15","dep":125}], 12414=[{"names":"aka","userId":"14","dep":124}, {"names":"aka1","userId":"14","dep":124}], 13614=[{"names":"aka4","userId":"14","dep":136}]}
--------------按某一属性分组后, 获取当前分组后Map的size 可用于统计
3
groupingBy 用意为将每一个元素按照某一种属性或多种属性执行分组操作,返回为map key 为分组的属性条件,值为当前元素
collectingAndThen 即执行集合操作后再执行某一方法
通过 stream 使一般的集合对象成为可以执行Stream 操作的对象
map 将每一个元素通过某些操作转化为另一种元素
Collectors 中
toMap 将每一种元素转为Map类型的结构,可以通过键拿到对应的元素,这里相当于是 数据库中通过id 获取某一条记录的数据一样,相当于自己建立了一个数据索引,对于数据暂存和优化以及操作十分方便,而且可以省去繁琐的简单操作将数据转为这一数据结构的过程,而且符合获取数据时的习惯。
toList 快速将多个元素转为List 而不用自己执行遍历操作
toSet 快速将多个元素转为set集合 可以用于去重操作
groupingBy 通过该方法可以快速对数据分组,同样省去了自己封装简单代码的过程
collectingAndThen 集合类操作和其他结果的聚合操作,同时是为了提升效率
虽然一般情况下不需要考虑代码的速度问题,但这里还是说一下Stream 的使用场景
经过对比,其实最简单的循环迭代方式对于较少和较简单的数据来说 for 等基本操作反而花费的时间是要比 Stream 快的。
这里我理解 Stream 是使用时间换来了代码的优化和简洁,但是对于不常使用Stream的人来说易读性并不太友好。
Stream 使用场景如下:
equals hashCode 为了对象比较一定需要重写 直接使用代码生成的即可
import java.util.Objects;
public class MyPerson {
private int id;
private String name;
public MyPerson() {
}
public MyPerson(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyPerson{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyPerson myPerson = (MyPerson) o;
return id == myPerson.id &&
Objects.equals(name, myPerson.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
public static MyPerson transEntity(String s){
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}