一 optional优雅判空
optional是个容器,它可以保存类型T的值,或者仅仅保存为null。optional提供很多有用的方法,这样我们不用显示进行空值判断,很好地解决空指针异常。
常用的方法
Optional.isPresent(value) 如果值存在方法返回true,否则返回false。
Optional.ofNullable(value).orElse(other)
ofNullable存在则返回该值,否则返回空。
orElse存在返回该值,否则返回other。
二 操作集合的stream流
stream可以使用一种声明的方式处理数据,代码更高效、干净、整洁。
将要处理的数据看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选、排序、聚合等。元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结果。
stream操作分为中间操作和终止操作,数据源可以是集合、数组。
中间操作:map, filter, sorted, distinct, limit。
终止操作:count, reduce, foreach, collect, anyMatch, allMatch, noneMatch, max, min。
下面列举几个常见应用:
public class TestStream { public static void main(String[] args) { List<Integer> list = Arrays.asList(2,5,5,2,0,9,6,7); Student sa = new Student(1,"zhangsan", 22, "001", "henan"); Student sb = new Student(2,"lisi", 28, "001", "chongqing"); Student sc = new Student(3,"wangwu", 25, "002", "hebei"); Student sd = new Student(4,"qianliu", 25, "001", "henan"); List<Student> objList = new ArrayList<>(); objList.add(sa); objList.add(sb); objList.add(sc); objList.add(sd); // foreach遍历 list.stream().forEach(x-> System.out.println(x)); // sorted;基本数据类型 Comparator.reverseOrder() 逆序排序,默认为升序 Integer max = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0); // sorted;对象类型 Comparator.comparing(Student::getAge) 根据某个属性排序,reversed 逆序 Student maxObj = objList.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList()).get(0); // map 映射;对象类型,将每一个元素映射为另一个元素 List<String> nameList = objList.stream().map(Student::getName).collect(Collectors.toList()); // map 映射;基本类型 list.stream().map(x -> x * 2).forEach(x -> System.out.println(x)); // filter 过滤;x > 5 是过滤条件,将满足过滤条件的元素输出 list.stream().filter(x -> x > 5).forEach(x -> System.out.println(x)); // distinct 去重 list.stream().distinct().forEach(x -> System.out.println(x)); // limit 截取元素 list.stream().limit(2).forEach(x -> System.out.println(x)); // count 获取元素个数 objList.stream().count(); // reduce 将流中所有元素合并为一个元素;此例中map与reduce相结合 objList.stream().map(Student::getAge).reduce((x1, x2) -> x1 + x2 + 2).get(); // 数组元素拼接为字符串;特殊符号分割 //System.out.println(StringUtils.join(list, ",")); // 对象类型,借助stream,将某个属性元素拼接 System.out.println(objList.stream().map(Student::getName).collect(Collectors.joining(",")).trim()); // list返回map -> Collectors.toMap;key:x -> x.getName(), value:x -> x Map<Integer, Student> stuMap = objList.stream().collect(Collectors.toMap(Student::getId, x -> x)); System.out.println(stuMap); // map返回list -> Collectors.toList() List<String> studentNameList = objList.stream().map(Student::getName).collect(Collectors.toList()); System.out.println(studentNameList); // list返回另一个list;对象转换,map(x->x{... return}) List<User> userList = objList.stream().map(x->{ return new User(x.getId(),x.getName(),x.getAge(),x.getCountryCode(),x.getProvince()); }).collect(Collectors.toList()); System.out.println(userList); // groupingBy 根据name字段分组 Collectors.groupingBy Map<String, List<Student>> groupMap = objList.stream().collect(Collectors.groupingBy(Student::getName)); System.out.println(groupMap); // groupingBy 分组之后,统计数量 Collectors.groupingBy 的第二个参数,还可以继续使用Collectors的参数 Map<String, Long> groupCount = objList.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting())); System.out.println(groupCount); // 根据countryCode, province分组 Map<String, Map<String, List<Student>>> countryMap = objList.stream().collect(Collectors.groupingBy(Student::getCountryCode, Collectors.groupingBy(Student::getProvince) )); System.out.println(countryMap); // partitioningBy 分区是分组的一种特殊情况,将数据分为true和false两组 /*Map<Boolean, Map<String,List<Student>> partitionMap = objList.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 5, Collectors.groupingBy(Student::getName))); System.out.println(partitionMap);*/ Map<Boolean, Map<String,Long>> partitionMap = objList.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 5, Collectors.groupingBy(Student::getName, Collectors.counting()))); System.out.println(partitionMap); } }