Java8实用技能

发布时间:2025-09-01 01:49:04 作者:益华网络 来源:undefined 浏览量(0) 点赞(0)
摘要:大概一年多之前,我对java8的理解还仅限一些只言片语的文章之上,后来出于对函数式编程的兴趣,买了本参考书看了一遍,然后放在了书架上,后来,当我接手大客户应用的开发工作之后,java8的一些工具,对我的效率有了不小的提升,因此想记录一下java’8的一些常用场景,我希

大概一年多之前,我对java8的理解还仅限一些只言片语的文章之上,后来出于对函数式编程的兴趣,买了本参考书看了一遍,然后放在了书架上,后来,当我接手大客户应用的开发工作之后,java8的一些工具,对我的效率有了不小的提升,因此想记录一下java’8的一些常用场景,我希望这会成为一个小字典,能让我免于频繁翻书,但是总能找到自己想找的知识。

用于举例的model:

@DatapublicclassApple{privateLong appleId;privateString appleName;privateFloat appleWeight;privateInteger appleClassic;}

一、Java 8 Lambda 表达式

这无疑是最常用的功能之一,其实lambda表达式的作用,应该就是简洁明了,实际上是用最短的字符,通过类型推导,语法糖等方式去对编译器描述清楚这段代码的功能,这和泛型有点相似,对于编程人员来说,一定程度上也提高了编程效率和代码可读性。

如常用的lambda表达式:

process(()->System.out.println(“this is so cool!”))

例如对苹果重量排序:

List<Apple> apples =Lists.newArrayList();for(int i =1; i <10; i++){Apple apple =newApple(); apples.add(apple);} apples.sort(Comparator.comparing(Apple::getAppleWeight));反序: apples.sort(Comparator.comparing(Apple::getAppleWeight).reversed());重量相同时:比较等级: apples.sort(Comparator.comparing(Apple::getAppleWeight).reversed()谓词复合查询:Predicate<Apple> a = apple -> apple.getAppleWeight()>10; weight10.or(apple -> apple.getAppleClassic()>2).and(apple ->StringUtils.equalsIgnoreCase(apple.getAppleName(),"优质苹果"));可以看做(a||b)&&c函数复合:Function<Apple,Float> f = a -> a.getAppleWeight()+1;Function<Float,Float> g = a -> a *2;Function<Apple,Float> h = f.andThen(g);数学写作 h=g(f(x))Function<Apple,Float> g = a -> a.getAppleWeight()+1;Function<Float,Float> f = a -> a *2;Function<Apple,Float> h = f.compose(g);数学写作 h=f(g(x))

小结:java8实际上想传递函数,函数是什么?是一个映射,可以看做x->y,输入x然后映射到值y的过程,

java无法摆脱一切皆是对象的思想,因此函数式依附在对象上传递的,因此也有了下面的说法,方法引用,以及函数式接口,让函数随着对象传递,为了函数式编程,甚至专门写一个接口—-对象来传递函数。然而,函数才是主角。

二、Java 8 方法引用

方法引用十分简单,其实也是将方法作为参数传递。使用::域作用符,将一段方法传递。

举例:Apple::getAppleId

String::subString

System.out::println

三、Java 8 函数式接口 函数式编程

利用java进行函数式编程主要就是利用函数式接口,但是函数式接口在java8之前就有一些了,就例如多线程的runnable,但是8以前是没有lambda表达式的,所以只能使用匿名内部类,在用过lambda表达式的人看来,那是相当臃肿的,8更新了lambda表达式,这就使函数式编程更上一层楼.

java8的函数式接口为我们传递函数提供了工具,我们可以自己定义函数式接口,然后让其他人,或者是java API调用。

关于函数接口,需要记住的就是两件事:

函数接口是行为的抽象;

函数接口是数据转换器。

四、Java 8 Stream

在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。其本质是,将一些原本开发者需要做的处理如迭代等,放在了java库里,让我们只关心自己的业务逻辑,比如我们希望对一个包含整数的集合中筛选出所有的偶数,并将其封装成为一个新的List返回,那么在java8之前,我们需要通过如下代码实现:

过去:List<Integer> evens =newArrayList<>();for(finalInteger num : nums){if(num %2==0){ evens.add(num);}}stream实现:List<Integer> evens = nums.stream().filter(num -> num %2==0).collect(Collectors.toList());我们需要取出10个等级高于3的苹果,跳过其中两个,按重量排序,去重,然后取出苹果的Name,然后取出名字的每个字符:List<String> appleName = apples.parallelStream().filter(a -> a.getAppleClassic()<2).sorted(Comparator.comparing(Apple::getAppleWeight)).map(Apple::getAppleName).map(s -> s.split("")).limit(10).skip(2).distinct().flatMap(Arrays::stream).collect(Collectors.toList());构造AppleIdApppleNameMap:Map<Long,String> appleIdMap = apples.stream().collect(Collectors.toMap(Apple::getAppleId,Apple::getAppleName,(s, s2)-> s.length()> s2.length()? s : s2));谓词查找:if(appleName.stream().anyMatch(a ->StringUtils.equalsIgnoreCase(a,"一级苹果")));if(appleName.stream().allMatch(a ->StringUtils.equalsIgnoreCase(a,"一级苹果")));if(appleName.stream().noneMatch(a ->StringUtils.equalsIgnoreCase(a,"一级苹果")));短路查找: appleName.stream().filter(a ->StringUtils.equalsIgnoreCase(a,"一级苹果")).findAny().ifPresent(System.out::println);findfirst在并行时限制多一些,如果不在意返回的是哪个元素,使用findAny求和: apples.stream().map(Apple::getAppleWeight).reduce(0F,(a, b)-> a + b);计数: apples.stream().count();

使用stream的好处:

1.更简洁,更易读

2.可复合,更灵活

3.可并行

五、Java 8 Optional 类

Optional着重为解决java的NPE问题是Java8提供的为了解决null安全问题的一个API。善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅。

使用Optional,我们就可以把下面这样的代码进行改写:publicstaticString getName(User u){if(u ==null)return"Unknown";return u.name;}不过,千万不要改写成这副样子。publicstaticString getName(User u){Optional<User> user =Optional.ofNullable(u);if(!user.isPresent())return"Unknown";return user.get().name;}这样才是正确使用Optional的姿势。那么按照这种思路,我们可以安心的进行链式调用,而不是一层层判断了。publicstaticString getName(User u){returnOptional.ofNullable(u).map(user->user.name).orElse("Unknown");}看一段代码:publicstaticString getChampionName(Competition comp)throwsIllegalArgumentException{if(comp !=null){CompResult result = comp.getResult();if(result !=null){User champion = result.getChampion();if(champion !=null){return champion.getName();}}}thrownewIllegalArgumentException("The value of param comp isnt available.");}让我们看看经过Optional加持过后,这些代码会变成什么样子。publicstaticString getChampionName(Competition comp)throwsIllegalArgumentException{returnOptional.ofNullable(comp).map(c->c.getResult()).map(r->r.getChampion()).map(u->u.getName()).orElseThrow(()->newIllegalArgumentException("The value of param comp isnt available."));}还有很多不错的使用姿势,比如为空则不打印可以这么写:string.ifPresent(System.out::println);

参考资料:《Java 8 in Action: Lambdas, streams, and functional-style programming》 Raoul-gabriel Urma (作者), Mario Fusco (作者), Alan Mycroft (作者)

作者:文烁

点击 阅读更多 查看更多详情

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!