全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2023-10-26_值得使用Lambda的8个场景,别再排斥它了!

您的位置:首页 >> 新闻 >> 行业资讯

值得使用Lambda的8个场景,别再排斥它了! 点击小卡片参与粉丝专属福利前言可能对不少人来说,Lambda显得陌生又复杂,觉得Lambda会导致代码可读性下降,诟病Lambda语法,甚至排斥。 其实所有的这些问题,在尝试并熟悉后,可能都不是问题。 对Lambda持怀疑态度的人,也许可以采取渐进式使用Lambda的策略。在一些简单和低风险的场景下先尝试使用Lambda,逐渐增加Lambda表达式的使用频率和范围。 毕竟2023年了,JDK都出了那么多新版本,是时候试试Lambda了! 耐心看完,你一定有所收获。 giphy.gif正文1. 对集合进行遍历和筛选:使用Lambda表达式结合Stream API可以在更少的代码量下实现集合的遍历和筛选,更加简洁和易读。 原来的写法: ListIntegernumbers=Arrays.asList(1,2,3,4,5); for(Integernum:numbers){ if(num%2==0){ System.out.println(num); } } 优化的Lambda写法: ListIntegernumbers=Arrays.asList(1,2,3,4,5); numbers.stream() .filter(num-num%2==0) .forEach(System.out::println); 2. 对集合元素进行排序:使用Lambda表达式可以将排序逻辑以更紧凑的形式传递给sort方法,使代码更加简洁。 原来的写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie","David"); Collections.sort(names,newComparatorString(){ publicintcompare(Stringname1,Stringname2){ returnname1.compareTo(name2); } }); 优化的Lambda写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie","David"); names.sort((name1,name2)-name1.compareTo(name2)); 3. 集合的聚合操作:Lambda表达式结合Stream API可以更优雅地实现对集合元素的聚合操作,例如求和、求平均值等。 原来的写法: ListIntegernumbers=Arrays.asList(1,2,3,4,5); intsum=0; for(Integernum:numbers){ sum+= } 优化的Lambda写法: ListIntegernumbers=Arrays.asList(1,2,3,4,5); intsum=numbers.stream() .reduce(0,Integer::sum); 4. 条件过滤和默认值设置:使用Lambda的Optional类可以更加优雅地处理条件过滤和默认值设置的逻辑。 原来的写法: Stringname="Alice"; if(name!=nullname.length()0){ System.out.println("Hello,"+name); }else{ System.out.println("Hello,Stranger"); } Lambda写法: Stringname="Alice"; name=Optional.ofNullable(name) .filter(n-n.length()0) .orElse("Stranger"); System.out.println("Hello,"+name); 5. 简化匿名内部类:可以简化代码,同时提高代码可读性。 举个创建Thread的例子,传统方式使用匿名内部类来实现线程,语法较为冗长,而Lambda表达式可以以更简洁的方式达到相同的效果。 原来的写法: newThread(newRunnable(){ publicvoidrun(){ System.out.println("Threadisrunning."); } }).start(); Lambda写法: newThread(()-System.out.println("Threadisrunning.")).start(); newThread(()-{ //做点什么 }).start(); 这种写法也常用于简化回调函数,再举个例子: 假设我们有一个简单的接口叫做Calculator,它定义了一个单一的方法calculate(int a, int b)来执行数学运算: //@FunctionalInterface:标识接口是函数式接口,只包含一个抽象方法,从而能够使用Lambda表达式来实现接口的实例化 @FunctionalInterface interfaceCalculator{ intcalculate(inta,intb); } 现在,让我们创建一个名为CallbackExample的类。该类有一个名为operate的方法,它接受两个整数和一个Calculator接口作为参数。该方法将使用提供的Calculator接口执行计算并返回结果: publicclassCallbackExample{ publicstaticintoperate(inta,intb,Calculatorcalculator){ returncalculator.calculate(a, } publicstaticvoidmain(String[]args){ intnum1=10; intnum2=5; //使用Lambda作为回调 intsum=operate(num1,num2,(x,y)-x+ intdifference=operate(num1,num2,(x,y)-x- intproduct=operate(num1,num2,(x,y)-x* intdivision=operate(num1,num2,(x,y)-x/ System.out.println("Sum:"+sum); System.out.println("Difference:"+difference); System.out.println("Product:"+product); System.out.println("Division:"+division); } } 通过在方法调用中直接定义计算的行为,我们不再需要为每个运算创建多个实现Calculator接口的类,使得代码更加简洁和易读 giphy (1).gif6. 集合元素的转换:使用Lambda的map方法可以更优雅地对集合元素进行转换,提高代码的可读性 原来的写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie"); ListStringuppercaseNames=newArrayList(); for(Stringname:names){ uppercaseNames.add(name.toUpperCase()); } Lambda写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie"); ListStringuppercaseNames=names.stream() .map(String::toUpperCase) .collect(Collectors.toList()); 7. 对集合进行分组和统计:以更紧凑的形式传递分组和统计的逻辑,避免了繁琐的匿名内部类的声明和实现。 通过groupingBy、counting、summingInt等方法,使得代码更加流畅、直观且优雅。 传统写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie","David","Amy","Diana"); //对名字长度进行分组 MapInteger,ListStringnamesByLength=newHashMap(); for(Stringname:names){ intlength=name.length(); if(!namesByLength.containsKey(length)){ namesByLength.put(length,newArrayList()); } namesByLength.get(length).add(name); } System.out.println("Namesgroupedbylength:"+namesByLength); //统计名字中包含字母'A'的个数 ListStringnames=Arrays.asList("Alice","Bob","Charlie","David","Amy","Diana"); intnamesWithA=0; for(Stringname:names){ if(name.contains("A")){ namesWithA++; } } System.out.println("Numberofnamescontaining'A':"+namesWithA); Lambda写法: ListStringnames=Arrays.asList("Alice","Bob","Charlie","David","Amy","Diana"); //使用Lambda表达式对名字长度进行分组 MapInteger,ListStringnamesByLength=names.stream() .collect(Collectors.groupingBy(String::length)); System.out.println("Namesgroupedbylength:"+namesByLength); //使用Lambda表达式统计名字中包含字母'A'的个数 longnamesWithA=names.stream() .filter(name-name.contains("A")) .count(); System.out.println("Numberofnamescontaining'A':"+namesWithA); 8. 对大数据量集合的并行处理当集合的数据量很大时,通过Lambda结合Stream API可以方便地进行并行处理,充分利用多核处理器的优势,提高程序的执行效率。 假设我们有一个包含一百万个整数的列表,我们想要计算这些整数的平均值: importjava.util.ArrayList; importjava.util.List; importjava.util.concurrent.ThreadLocalRandom; publicclassParallelStreamExample{ publicstaticvoidmain(String[]args){ //创建一个包含一百万个随机整数的列表 ListIntegernumbers=newArrayList(); for(inti=0;i1000000;i++){ numbers.add(ThreadLocalRandom.current().nextInt(100)); } //顺序流的处理 longstartTimeSeq=System.currentTimeMillis(); doubleaverageSequential=numbers.stream() .mapToInt(Integer::intValue) .average() .getAsDouble(); longendTimeSeq=System.currentTimeMillis(); System.out.println("SequentialAverage:"+averageSequential); System.out.println("Timetaken(Sequential):"+(endTimeSeq-startTimeSeq)+"ms"); //并行流的处理 longstartTimePar=System.currentTimeMillis(); doubleaverageParallel=numbers.parallelStream() .mapToInt(Integer::intValue) .average() .getAsDouble(); longendTimePar=System.currentTimeMillis(); System.out.println("ParallelAverage:"+averageParallel); System.out.println("Timetaken(Parallel):"+(endTimePar-startTimePar)+"ms"); } } 分别使用顺序流和并行流来计算列表中整数的平均值: 顺序流:通过stream()方法获取流,使用mapToInt将Integer转换为int,然后使用average()方法计算平均值并行流:使用parallelStream()方法获取并行流,其他步骤与顺序流相同查看输出结果: Sequential Average: 49.517461 Time taken (Sequential): 10ms Parallel Average: 49.517461 Time taken (Parallel): 3ms 可以看出,顺序流和并行流得到了相同的平均值,但并行流的处理时间明显少于顺序流。因为并行流能够将任务拆分成多个小任务,并在多个处理器核心上同时执行这些任务。 当然并行流也有缺点: 对于较小的数据集,可能并行流更慢数据处理本身的开销较大,比如复杂计算、大量IO操作、网络通信等,可能并行流更慢可能引发线程安全问题收尾Lambda的使用场景远不止这些,在多线程、文件操作等场景中也都能灵活运用,一旦熟悉后可以让代码更简洁,实现精准而优雅的编程。 写代码时,改变偏见需要我们勇于尝试和付诸行动。有时候,我们可能会对某种编程语言、框架或设计模式持有偏见,认为它们不适合或不好用。但是,只有尝试去了解和实践,我们才能真正知道它们的优点和缺点。 当我们愿意打破旧有的观念,敢于尝试新的技术和方法时,我们就有机会发现新的可能性和解决问题的新途径。不要害怕失败或犯错,因为每一次尝试都是我们成长和进步的机会。 只要我们保持开放的心态,不断学习和尝试,我们就能够超越偏见,创造出更优秀的代码和解决方案。 所以,让我们在编程的路上,积极地去挑战和改变偏见。用行动去证明,只有不断地尝试,我们才能取得更大的进步和成功。让我们敢于迈出第一步,勇往直前,一同创造出更美好的编程世界! 如果文章对你有帮助的话欢迎「关注+点赞+收藏」 阅读原文

上一篇:2025-06-28_史上最长618回顾:3个关键词,10个小发现 下一篇:2023-04-08_通用视觉GPT时刻来临?智源推出通用分割模型SegGPT

TAG标签:

13
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价