1.
//具体用法
// putIfAbsent 和 computeIfAbsent 都是针对map里没有key对应的元素进行操作,
// putIfAbsent(Object key ,Object value ) ;computeIfAbsent(Object key , Function) Function是可以code的
// key有对应的value值不进行操作,并返回这个旧值
// key没有有对应的value值 进行操作 操作 :putIfAbsent 放入newValue ;computeIfAbsent 放入newValue
先上才艺:
/java 8 map (并发map和普通hashMap 都有) 的 常用方法
//说明:假设有这么一个容器 Map<String, List> concurrentHashMap = new ConcurrentHashMap<>()
//有一些学生,年龄介于20到22之间,要根据年龄对这些学生分组
// java
List<Student> studentList = Arrays.asList(
new Student("xiaoming20","20"),new Student("lihua20","20"),new Student("wumei20","20"),
new Student("xiaoming21","21"),new Student("lihua21","21"),new Student("wumei21","21"),
new Student("xiaoming22","22"),new Student("lihua22","22"),new Student("wumei22","22")
);
//法① list.stream().collect(Collectors.groupingBy(User::getType));
Map<String,List<Student>> studentGroupMap1 = studentList.stream().collect(Collectors.groupingBy(Student::getAge));
//java 8 之前
Map<String, List> before8Map = new ConcurrentHashMap<String, List>();
for (Student student : studentList) {
if(CollectionUtils.isEmpty(before8Map.get(student.getAge()))){
List stuList = new ArrayList<Student>();
stuList.add(student);
before8Map.put(student.getAge(),stuList);
}else{
List stuList = before8Map.get(student.getAge());
stuList.add(student);
};
}
//java 8 之后,除了法① ,还可以用 putIfAbsent key没有value就创建,有的话直接拿出来,不用自己判断
Map<String, List> after8Map = new ConcurrentHashMap<String, List>();
studentList.stream().forEach(student ->{
List<Student> groupList = after8Map.computeIfAbsent(student.getAge() , value->{
return new ArrayList<Student>();
});
//对拿出来的集合操作,不进行这一步,after8Map 拿出来的三个集合都是空的
groupList.add(student);
});
System.out.println(studentGroupMap1.toString());
System.out.println(before8Map.toString());
System.out.println(after8Map.toString());
Map<String, List> concurrentHashMap = new ConcurrentHashMap<>();
//判断容器里 list 的value ,value 为null 就创建一个,否则拿出来
List list = concurrentHashMap.computeIfAbsent("list", k -> {
return new ArrayList<String>();
});
list.add("hello");
// list.add("hello") 是在数组里的 List集合进行操作,根据list再次找到这个list ,发现list1 也是有值的
List list1 = concurrentHashMap.get("list");
//在map中已经存在的key的value进行操作。只对已经存在key的进行操作,其他不操作,下面的操作没用
// list2 为 null
List list2 = concurrentHashMap.computeIfPresent("list2" ,(k,v) -> {
return new ArrayList(10);
});
// list3 有个元素:hello
List list3 = concurrentHashMap.computeIfAbsent("list", k -> {
return new ArrayList<String>();
});
list3.add("word");
//"list" 有对应的value,则返回旧的value,不继续执行 new ArrayList<String>() 这个操作
List list4 = concurrentHashMap.computeIfAbsent("list", k -> {
return new ArrayList<String>();
});
//list4 有两个元素
//System.out.println(list4.size());
//
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("1","1");
String result = map.putIfAbsent("1","2");
String result2 = map.get("1");
map.putIfAbsent("2","2");
String result3 = map.get("2");
打印结果如下:
{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}
{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}
{22=[Student{name='xiaoming22', age='22'}, Student{name='lihua22', age='22'}, Student{name='wumei22', age='22'}], 20=[Student{name='xiaoming20', age='20'}, Student{name='lihua20', age='20'}, Student{name='wumei20', age='20'}], 21=[Student{name='xiaoming21', age='21'}, Student{name='lihua21', age='21'}, Student{name='wumei21', age='21'}]}
所以函数式表达式的用处:
作为方法A中形参参数:将函数式接口作为形参;实际上调用方法A的时候用lamda表达式的方法体 去实现函数式接口 里的抽象方法(ps:貌似就是 一个函数式接口 有很多实现)
例子:
自定义一个函数式接口:
@FunctionalInterface
public interface MyFunctionInterface<Integer> {
java.lang.Integer apply(java.lang.Integer t);
}
该接口定义一个抽象方法,没有方法体(方法体是在 作为实参的时候 lamda表达式 的 方法体中实现的)
public int getAndIncrement(MyFunctionInterface<Integer> functionInterface ,int a ) {
return functionInterface.apply(a);
}
函数接口对 a 进行操作
// 调用 getAndIncrement方法
System.out.println("---------");
MyTest myTest = new MyTest();
int b = myTest.getAndIncrement(e ->{
//10
System.out.println(e);
return e+100;
},10);
//110
System.out.println(b);
例子2:
定义一个函数式接口,这个函数接口的作用是对两个形参求和
@FunctionalInterface
public interface SumFunctionInterface {
java.lang.Integer getSum(java.lang.Integer t1,java.lang.Integer t2);
}
public int getSum(int a , int b,SumFunctionInterface functionInterface ) {
return functionInterface.getSum(a,b);
}
// 调用 getSum 方法
System.out.println("---------");
MyTest myTest = new MyTest();
int c = myTest.getSum(100,1000,(a,b) ->{
//100
System.out.println(a);
//1000
System.out.println(b);
return a+b;
});
//1100
System.out.println(c);