lambda 详解

  • 前提
	    List<User> all = new ArrayList<User>();
		Wrapper<User> queryWrapper = new QueryWrapper<>();
		all = userMapper.selectList(queryWrapper);
  • 一个对象的集合转化成另一个对象的集合( 可以是自己新建的DTO,里面取的字段可以是通过构造方法)

		List<UserVo> cartDTOList = all.stream().map(e -> new UserVo(e.getId(), e.getPassword(), e.getUsername())).collect(toList());

  • 过滤集合
        Stream<User> alltream = all.stream().filter(a -> a.getUsername().indexOf("z") > 0);
        List<User> collect = alltream.collect(toList());//stream<User>转换成List<User>
        System.out.println(collect.size());
        collect.forEach(
                e -> System.out.println("过滤集合中的字符串:" + JSON.toJSONString(e))
        );
  • 数组转字符串,字符串转数组,集合转字符串,字符串转集合
        int[] arr = {1, 2, 3, 4};
        //1、数组转逗号分隔的字符串
        String strArr = Arrays.stream(arr).boxed().map(i -> i.toString()).collect(Collectors.joining(","));
        System.out.println("int类型数组转字符串:" + strArr);
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");

        //2、集合转逗号分隔的字符串
        String strList = list.stream().collect(Collectors.joining(","));
        System.out.println("integer类型的集合转字符串" + strList);
        List<Integer> listInt = new ArrayList<>();
        listInt.add(1);
        listInt.add(2);
        listInt.add(3);
        listInt.add(4);
        listInt.add(1);

        //集合转逗号分隔的字符串-去重
        String str3 = listInt.stream().map(r -> r.toString()).distinct().collect(Collectors.joining(","));
        System.out.println("integer类型的集合转字符串去重:" + str3);

        //3、逗号分隔的字符串转成集合
        String ids = "1,2,3,4,5,6";
        List<Long> idss = Arrays.asList(ids.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(toList());
        idss.forEach(
                e -> System.out.println("逗号分隔的字符串转long类型的集合:" + e.toString())
        );

        //4、逗号分隔的字符串转数组
        String strToArrayList = "1,2,3,4,5,6";
        List<Long> listIds = Arrays.asList(ids.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        System.out.println(Arrays.toString(listIds.toArray()));

  • 数组集合互转
        String ids = "1,2,3,4,5,6";
        List<Long> idss = Arrays.asList(ids.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(toList());
        /**
         * @Description:传统方式数组和list互转如下:
         * @Author: wumingdu
         * @Date: 2020/11/17 22:01
         */
        //集合转数组
        Object[] objects = (Object[]) idss.toArray();
        for (int i = 0; i < objects.length; i++) {
            //  System.out.println(objects[i].toString());
        }
        //数组转集合
        List longs = Arrays.asList(objects);
        // System.out.println(longs.toString());

        /**
         * 使用lambda 的方式转换如下:
         */
        //数组转换成list
        String[] arrays = {"a", "b", "c"};
        List<String> listStrings = Stream.of(arrays).collect(toList());
        System.out.println(listStrings);

        //List转换为数组
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        String[] strings = list.stream().toArray(String[]::new);
        System.out.println(strings);
  • map转list
        Map<String, String> map = new HashMap<>();
        map.put("1", "AAAA");
        map.put("2", "BBBB");
        map.put("3", "CCCC");
        map.put("4", "DDDD");
        map.put("5", "EEEE");
        List<User> list = map.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey())).map(e -> new User(Long.parseLong(e.getKey()), e.getValue())).collect(Collectors.toList());
        
        //将map里面的每对entrySet当做一个对象放进list中
        List<Object> map2list1 = map.entrySet().stream().map(et -> et).collect(Collectors.toList());
        
        //将map中k和v 当做对像中的两个属性set到对象中
        List<User> map2list2 = map.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey())).map(e -> new User(Long.parseLong(e.getKey()), e.getValue())).collect(Collectors.toList());
        
        List<User> map2list3 = map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).map(e -> new User(Long.parseLong(e.getKey()), e.getValue())).collect(Collectors.toList());
        
        List<User> map2list4 = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(e -> new User(Long.parseLong(e.getKey()), e.getValue())).collect(Collectors.toList());

  • list转map
        //将集合种的对象的两个属性取出来,方法map中
        Map<Long, String> result1 = all.stream().collect(Collectors.toMap(User::getId, User::getUsername));
        
        //将集合种的对象的两个属性取出来,方法map中(其中一个就是对象本身)
        Map<Long, Object> result2 = all.stream().collect(Collectors.toMap(User -> User.getId(), User -> User.getUserVo()));
        
        //将集合种的对象的两个属性取出来,方法map中(如果有重复的,就将重复的单独放进集合中)
        Map<String, ArrayList<User>> result3 = all.stream().collect(Collectors.toMap(User -> User.getUsername(), User -> Lists.newArrayList(User), (ArrayList<User> oldList, ArrayList<User> newList) -> {
            oldList.addAll(newList);
            return oldList;
        }));

        //list<user>===>list<map>
        List<Map<String, Object>> personToMap = all.stream().map((p) -> {
            Map<String, Object> mp = new HashMap<>();
            mp.put("name", p.getId());
            mp.put("age", p.getUsername());
            return mp;
        }).collect(Collectors.toList());

        //或者
        List<Map<String,Object>> personToMap2 = all.stream().collect(ArrayList::new, (listsssss, p) -> {
            Map<String, Object> qqqqqqqq = new HashMap<>();
            qqqqqqqq.put("id", p.getId());
            qqqqqqqq.put("username", p.getUsername());
            listsssss.add(qqqqqqqq);
        }, List::addAll);

        //list<user>===>list<map>
        List<Map<String, Object>> mapList = all.stream().map(user -> MapGetterTool.bean2Map(user)).collect(Collectors.toList());

        List<Object> List2map = mapList.stream().map(user -> MapGetterTool.mapToObject(user,User.class)).collect(Collectors.toList());


  • list转map防止k重复
        Map<String, User> collect2 = all.stream().collect(Collectors.toMap(User::getUsername, Function.identity(), (key1, key2) -> key2));

        Map result = all.stream().collect(HashMap::new, (map2, p) -> map2.put(p.getId(), p.getUsername()), Map::putAll);

        LinkedHashMap<String, User> collect3 = all.stream().collect(Collectors.toMap(User::getUsername, Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));

  • lis《user》转list《String》
        List<String> userNameList = all.stream().map(e -> new String(e.getUsername())).collect(Collectors.toList());
        
        List<Long> idList = all.stream().map(e -> new Long(e.getId())).collect(Collectors.toList());
        
        List<Date> dateList = all.stream().map(e -> new Date(String.valueOf(e.getUpdated()))).collect(Collectors.toList());
        
        List<String> dateList_str = all.stream().map(e -> new String(String.valueOf(e.getUpdated()))).collect(Collectors.toList());
  • 分组
        Map<String, List<User>> groupBy = all.stream().collect(Collectors.groupingBy(User->User.getUsername()));

  • 排序
		//返回 对象集合以类属性一升序排序
		list.stream().sorted(Comparator.comparing(类::属性一));
		
		//返回 对象集合以类属性一降序排序 注意两种写法
		list.stream().sorted(Comparator.comparing(类::属性一).reversed());//先以属性一升序,结果进行属性一降序
		 
		list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()));//以属性一降序
		
		//返回 对象集合以类属性一降序 属性二升序 注意两种写法
		list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二));//先以属性一升序,升序结果进行属性一降序,再进行属性二升序
		 
		list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二));//先以属性一降序,再进行属性二升序

		
		// 中文排序
        Collections.sort(lists, (Persono1, Persono2) -> Collator.getInstance(Locale.CHINESE).compare(o1.getName(), o2.getName()));

		通过以上例子我们可以发现
		1. Comparator.comparing(类::属性一).reversed();
		2. Comparator.comparing(类::属性一,Comparator.reverseOrder());
		两种排序是完全不一样的,一定要区分开来 1 是得到排序结果后再排序,2是直接进行排序,很多人会混淆导致理解出错,2更好理解,建议使用2
  • 去重
		我们知道, Java8 lambda自带的去重为 distinct 方法, 但是只能过滤整体对象, 不能实现对象里的某个值进行判定去重, 比如:
		List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 5, 5, 5, 6, 7);
		List<Integer> distinctNumbers = numbers.stream().distinct().collect(Collectors.toList());
		System.out.println(distinctNumbers);//1, 2, 3, 4, 5, 6, 7
		
		1、但是, 如果我们有一个 List<User> 类似这样的对象, 要对 User 的 name 进行条件去重怎么办?我们想要的效果是这样的:
		public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
   		 		Map<Object, Boolean> seen = new ConcurrentHashMap<>();
   			    return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
		}
		List<User> users = new LinkedList<>();
		users.add(new User("Jim"));
		users.add(new User("Jim"));
		users.add(new User("Tom"));
		users.add(new User("Leo"));

		List<User> distinctUsers = users.stream()  .filter(distinctByKey(User::getName)).collect(Collectors.toList());
		System.out.println(distinctUsers);//[Jim, Tom, Leo]
		
       2、JDK8 Stream操作 collectingAndThen
      先进行收集处理,然后将处理的集合结果 可以看到第一个参数是Collector接口的子类,所以还是对于对于Collector的处理,Collectors工具类里面的toList()、toSet()、joining()、mapping()、collectingAndThen()等几乎所有的方法都可以使用,这样感觉这个collectingAndThen就很强大了,可以嵌套的去使用。   第二个参数是一个Function函数,熟悉的同学都知道,Function函数是这样的:R apply(T t),这个也是理解上面去重式子的关键,原来我想的是ArrayList::new调用的无参的构造方法,其实他调用的ArrayList的有参构造方法,
       
        List<User> distinctList = all.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<User>(Comparator.comparing(o -> o.getUsername()))),ArrayList::new));
        System.out.println(JSON.toJSONString(distinctList));
  • 求和、最大、最小
		//最小
        Date minEntryDate = userList.stream().map(User::getEntryDate).min(Date::compareTo).get();
 
        //最大
        Date maxEntryDate = userList.stream().map(User::getEntryDate).max(Date::compareTo).get();
        
		//求和
        //基本类型
        int sumAge = userList.stream().mapToInt(User::getAge).sum();
        
        //BigDecimal求和
        BigDecimal totalQuantity = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);

		上面的求和不能过滤bigDecimal对象为null的情况,可能会报空指针,这种情况,我们可以用filter方法过滤,或者重写求和方法
;
	    public class BigDecimalUtils {
	    public static BigDecimal ifNullSet0(BigDecimal in) {
	        if (in != null) {
	            return in;
	        }
	        return BigDecimal.ZERO;
	    }
	    public static BigDecimal sum(BigDecimal ...in){
	       		 BigDecimal result = BigDecimal.ZERO;
		        for (int i = 0; i < in.length; i++){
		            result = result.add(ifNullSet0(in[i]));
		        }
	       		 return result;
	 		   }
	     }
	     
		使用重写的方法
		BigDecimal totalQuantity2 = userList.stream().map(User::getFamilyMemberQuantity).reduce(BigDecimal.ZERO, BigDecimalUtils::sum);


  • 对象判空
		stream.filter(x -> x!=null)
		
		stream.filter(Objects::nonNull)

  • 字段判空
		stream.filter(x -> x.getDateTime()!=null)

  • 批量设置list列表字段为同一个值
		addList.stream().forEach(a -> a.setDelFlag("0"));

  • 集合交集、并集、差集、去重
        List<String> list1 = new ArrayList<String>();
        list1.add("1");
        list1.add("2");
        list1.add("3");
        list1.add("5");
        list1.add("6");

        List<String> list2 = new ArrayList<String>();
        list2.add("2");
        list2.add("3");
        list2.add("7");
        list2.add("8");
        // 交集
        List<String> intersection = list1.stream().filter(item -> list2.contains(item)).collect(toList());
        System.out.println("---交集 intersection---");
        intersection.parallelStream().forEach(System.out::println);//将集合循环打印

        // 差集 (list1 - list2)   list1:1、2、3、5、6 - list2:2、3、7、8
        List<String> reduce1 = list1.stream().filter(item -> !list2.contains(item)).collect(toList());
        System.out.println("---差集 reduce1 (list1 - list2)---");
        reduce1.parallelStream().forEach(System.out::println);

        // 差集 (list2 - list1)
        List<String> reduce2 = list2.stream().filter(item -> !list1.contains(item)).collect(toList());
        System.out.println("---差集 reduce2 (list2 - list1)---");
        reduce2.parallelStream().forEach(System.out::println);
        // 并集
        List<String> listAll = list1.parallelStream().collect(toList());
        List<String> listAll2 = list2.parallelStream().collect(toList());
        listAll.addAll(listAll2);
        System.out.println("---并集 listAll---");
        listAll.parallelStream().forEachOrdered(System.out::println);//输出顺序与元素顺序一致

        // 去重并集
        List<String> listAllDistinct = listAll.stream().distinct().collect(toList());//[1, 2, 3, 5, 6, 2, 3, 7, 8]
        System.out.println("---得到去重并集 listAllDistinct---");
        listAllDistinct.parallelStream().forEachOrdered(System.out::println);
        System.out.println("---原来的List1---");
        list1.parallelStream().forEachOrdered(System.out::println);
        System.out.println("---原来的List2---");
        list2.parallelStream().forEachOrdered(System.out::println);
上一篇:谷粒商城day58-商品服务-API-新增商品-获取分类关联的品牌+获取分类下所有分组以及属性


下一篇:java8 功能比较强大的两个终止操作 reduce和collect