lambda 详解

  • 前提
	    List<User> all = new ArrayList<User>();
		Wrapper<User> queryWrapper = new QueryWrapper<>();
		all = userMapper.selectList(queryWrapper);

当我们使用Stream时,要将它转换成其他容器或Map。这时候,就会使用到Function.identity()。

Stream<String> stream = Stream.of("This", "is", "a", "test");
Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));

||
||
||
\/
private static Map<String, Task> taskMap(List<Task> tasks) {
  return tasks.stream().collect(toMap(Task::getTitle, task -> task));
}

  • 一个对象的集合转化成另一个对象的集合( 可以是自己新建的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);
### 大数据分析中的Lambda架构详解 #### Lambda架构概述 Lambda架构是一个实时大数据处理框架,最初由Nathan Marz于2011年提出,旨在解决大规模数据处理需求下的高效能与灵活性问题[^1]。该架构不仅能够支持批量离线处理还能满足实时数据处理的要求。 #### 应用场景 此架构尤其适合那些需要处理海量数据集并且期望获得低延迟查询结果的应用场合,比如用于创建动态更新的仪表盘或是生成即时报表等功能。除此之外,在涉及复杂的数据预处理操作如清洗、换及汇总等方面表现优异;同样也擅长执行流式计算任务,例如事件驱动逻辑实现、训练机器学习算法模型、识别异常行为模式乃至防范金融诈骗活动等。另外值得注意的是,基于其强大的吞吐能力和灵活扩展特性,Lambda架构常被用来搭建所谓的“数据湖”,即一种可以容纳多种形式原始资料(无论是结构化的还是半/非结构化的)的大规模分布式文件系统,并且对于来自IoT传感器网络所产生的连续不断的信息洪流具备良好的适应能力[^2]。 #### 架构组成部分 整个体系主要分为三个核心部分: - **Batch Layer (批处理层)** 批处理层专注于对过去积累下来的历史记录进行全面而精确地加工整理工作,确保最终得到的结果绝对可靠无误。这一环节通常会采用MapReduce这样的经典技术手段来进行长时间跨度内的全局状态维护。 - **Speed Layer (速度层)** 作为补充机制存在的速度层,则更侧重于捕捉当下正在发生的瞬息万变的新鲜资讯,以便迅速作出反应并向用户提供近似最新的统计概况。这里可能会借助Storm这类专为高速度消息传递优化过的引擎完成增量式的局部修正作业。 - **Serving Layer (服务层)** 最终经过上述两道工序精心打磨后的成品会被送入到服务层当中去供外部调用访问。这一步骤涉及到如何有效地组织管理已有的知识资产使之易于检索利用的问题,往往依赖像Elasticsearch这样优秀的全文搜索引擎来达成目的[^3]。 #### 组件选型策略 当考虑具体的技术栈组合方案时,应当充分认识到视图(View)这个概念在整个流程里扮演着至关重要的角色——它是连接底层基础设施同上层应用界面之间的桥梁纽带。因此,在挑选合适的工具链之前务必要深刻理解待解决问题域内所特有的业务语境及其背后隐藏的价值诉求点所在,进而有针对性地评估候选对象能否很好地契合实际应用场景的具体情况。不同类型的视图可以根据各自特定的任务性质分别选用最匹配的那一款产品或平台,而不必强求统一标准[^4]。 ```python # Python伪代码示例展示了一个简单的Lambda架构模拟过程 from batch_layer import BatchProcessor from speed_layer import SpeedProcessor from serving_layer import ServingLayer def lambda_architecture_simulation(data_stream, historical_data): # 初始化各层次处理器实例 batch_processor = BatchProcessor() speed_processor = SpeedProcessor() serving_layer = ServingLayer() # 对历史数据进行全量处理 processed_historical_data = batch_processor.process(historical_data) # 实时处理新流入的数据片段 real_time_updates = speed_processor.process(data_stream) # 将两者结合起来形成完整的最新视图 combined_view = merge_views(processed_historical_data, real_time_updates) # 更新至服务层以备后续查询请求使用 serving_layer.update(combined_view) ```
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值