文档章节

Java8 学习

learn_more
 learn_more
发布于 2016/06/28 21:09
字数 2254
阅读 463
收藏 25

每次写完代码不是一阵阵成就感,反而是挫败感加强,为什么呢?原因就是Java8特性没有使用上,导致代码的警告随处可见,作为一个程序员是不允许出现不完美的东西的,所以学习Java8迫在眉睫。啊,我一定要改变习惯,使用Java8,喊喊口号可能对自己有点安慰。

 

1、接口中可以添加非抽象方法

1)Java8 以前只允许抽象类既有抽象方法也可以由非抽象方法。

2)接口中添加非抽象方法需要使用 default 关键字限定使用。

3)功能性接口,接口只有一个抽象方法,可以有任意多个 default 声明的非抽象方法。这种接口在Lambda表达式中非常有用。Java8 提供注解 @FunctionalInterface 来限定功能性接口定义。

4)代码演示

 public interface Iter{

   default sayHello(){

        System.out.print("hello world");

   } 

 }

 

2、功能性接口

1)接口只有一个抽象方法,可以有任意多个 default 声明的非抽象方法。

2)使用 @FunctionalInterface 来限定功能性接口定义。

3)Lambda表达式结合使用

4)代码演示

@FunctionalInterface

interface Converter<F, T> {

    T convert(F from);

}

// 就是匿名实现类的对象,但是因为结合了Lambda表达式,所以简洁了很多

Converter<String, Integer> converter = (from) -> Integer.valueOf(from);

Integer converted = converter.convert("123");

 

3、:: 的使用,方法的引用

1)java8可以让你通过关键字 :: 来传递方法和构造函数的引用。

2)同样需要结合Lambda表达式,反正我是没有看到在没有Lambda表达式的情况下他是如何传递引用的。

3)静态方法和非静态方法都支持,静态方法使用类名,非静态方法使用类的对象。

4)使用 Class::new 的方式,可以创建一个简单的工厂模式,而且Lambda可以自动识别参数来找到对应的构造方法。

5)代码演示

Converter<String, Integer> converter = Integer::valueOf;

Integer converted = converter.convert("123");

 

4、Lambda 表达式

1)每个Lambda表达式都对应一个指定的类型,这个指定的类型是由接口确定。所以只能使用功能性接口时才可以使用 Lambda 表达式,否则类型无法匹配发生错误。

2)使用Lambda表达式有以下变化

     1、 匿名类可以省略。不需要显示指出实现具体接口的名称,Lambda可以自动推测接口

     2、 数据类型可以省略。不需要显示指定功能接口方法的形参类型,同样 Lambda 可以自动推测数据类型

     3、 花括号可以省略。如果只有一条语句,可以省略花括号,多条语句时必须使用花括号限定

     4、 return 可以省略。如果只有一条语句,可以省略return,多条语句时必选使用return关键字

     5、 但是多了一个 ->

3)Lambda和匿名函数一样,变量和方法的分大同小异。匿名函数调用的外部变量必须使用 final 关键字显示声明,否则编译报错;虽然,Lambda表达式可以调用非final声明的变量,但是实际上编译器作了自动转换 final,所以其实二者是一样的。

4)Lambda表达式中不能调用功能接口的 default 声明的方法,这个很特别啊,匿名函数自然是可以的。至于Lambda为什么不可以,我也不知道。

5)代码演示

        List<String> list = Arrays.asList("hello","world");

        // Java5

        Collections.sort(list, new Comparator<String>() {

            @Override

            public int compare(String o1, String o2) {

                return -(o1.compareTo(o2));

            }

        });

        // Java8

        Collections.sort(list, (a,b)->a.compareTo(b));

 

5、Java8 升级的功能性接口

1)断言接口(Predicates),Predicates是只拥有一个参数的Boolean型功能的接口。

    Predicate<Boolean> nonNull = Objects::nonNull;  // Objects 是 Java7 出来的 Object 对象帮助类

    Predicate<Boolean> isNull = Objects::isNull;

    Predicate<String> isEmpty = String::isEmpty; // 功能接口的方法是 test , 只要 isEmpty.test(obj)

    Predicate<String> isNotEmpty = isEmpty.negate(); // !isEmpty.test(obj) 等价

 

2)功能接口(Functions),Functions接受一个参数并产生一个结果。默认方法能够用于将多个函数链接在一起。功能 apply 方法接收任意参数,返回任意参数。(apply 有形参,有返回)

        Function<String, Integer> toInteger = Integer::valueOf;

        System.out.println(toInteger.apply("123")); // 123 Integer

        Function<String, String> backToString = toInteger.andThen(a->a+4+"");

        System.out.println(backToString.apply("123"));     // "127" String

 

3)供应接口(Suppliers),Suppliers对于给定的泛型类型产生一个实例。不同于Functions,Suppliers不需要任何参数,同样有任意类型的返回结果。(get 无形参,有返回)

        Supplier<Object> supplier = Object::new;

        Object obj = supplier.get();   // new Object,对象工厂

        System.out.println(Objects.toString(obj));

 

4)消费接口(Consumers),Consumers 代表在只有一个输入参数时操作被如何执行。实际上就是对一个输入参数的方法做一个统一的接口,注意他没有返回值。(accept 有形参,无返回)

        Consumer<String> consumer = (str) -> System.out.println("Hello, " + str);

        consumer.accept("World!");

 

5)比较接口(Comparators),Java8 在以前的基础上添加了许多方法,这里 Comparator 除了有 default 声明的方法之外,还有许多 static 的方法。

以前学习Java的时候明确指定静态方法不能被重写,所以接口中不应该出现static方法,因为接口中的方法就是需要子类去实现的,不能被重写和实现导致冲突,然而现在,接口中有了default,也有了static的方法,感觉接口已经不是以前那么单纯的接口了,反而是一些方法的集合体。

Comparator<String> comparator = (p1, p2) -> p1.compareTo(p2);

comparator.reversed().compare(p1, p2);  // < 0

 

6)选项接口(Optionals),Optionals并不是功能性接口,它是一种工具,比如有 map 、filter 等方法。 类的声明 public final class Optional<T>

        Optional<String> optional = Optional.of("bam");

        optional.isPresent();           // true

        optional.get();                 // "bam"

        optional = optional.map(a-> a+" died"); // bam died 

 

7)流接口(Streams),主要改变是 链式调用,串行操作,并行操作 

java.util.Stream代表着一串你可以在其上进行多种操作的元素。流操作既可以是连续的也可以是中断的。中断操作返回操作结果。而连续操作返回流本身,这样你就可以在该行上上继续操作。流是创建在数据源上的,例如:java.util.Collection、list集合和set集合。流操作既可以顺序执行也可以并行执行。

        List<String> list = Arrays.asList("1","5","3");

        list.stream().forEach(System.out::print); // 串行遍历集合

        list.parallelStream().forEach(System.out::print); // 并行遍历集合

        list.sort((a,b)-> - a.compareTo(b)); // 排序

        list.forEach(System.out::print); // 遍历

 

8)流接口下运用的方法(Filter)、(Sorted),(Map),(Match)、(Count)、(Reduce)

1)Filter接受一个predicate来过滤流中的所有元素。这个操作是连续的。ForEach接受一个consumer,它被用来对过滤流中的每个元素执行操作。ForEach是一个中断操作,因此我们不能在ForEach后调用其他流操作。

2)Sorted是一个连续操作,它返回流的已排序版本。如果你没有显示的指定Comparator,那么流中元素的排序规则为默认的。

3)连续性操作map通过指定的Function将流中的每个元素转变为另外的对象。

4)各种匹配操作可以用来检测是否某种predicate和流中元素相匹配。所有的这些操作是中断的并返回一个boolean结果。

5)Count是中断型操作,它返回流中的元素数量。这个和 size 很相似,当然是有差异的,size是对象本身的长度,count是对象副本的长度。

6)Reduce中断性操作使用指定的function对流中元素实施消减策略。此操作的返回值是一个包括所有被消减元素的Optional。

        list.stream().filter(value->Objects.equals(value,"5")).forEach(System.out::print); // 这里需要注意,list本身并没有发生改变,改变只是连续操作的对象副本。

        list.stream().sorted((a,b)->a.compareTo(b)).forEach(System.out::print); // 同上,排序不会改变List对象本身,改变的是操作流对象副本。

        list.stream().map(value->value+"_suffix").forEach(System.out::print); // 同上,List对象本身不会被改变

        System.out.println(list.stream().anyMatch(value->value.equals("5")));

        System.out.println(list.stream().allMatch(value->value.equals("5")));

        System.out.println(list.stream().noneMatch(value->value.equals("5")));

        System.out.println(list.stream().count() == list.size());

        Optional o = list.stream().reduce((s, s2) -> s+"_"+s2); o.ifPresent(System.out::print); // 1_5_3 

 

9)Map 新增操作

1)使用 foreach 遍历集合 

2)使用compute操作一对指定key的映射

        map.putIfAbsent(null,"empty"); // 使用 put 可以存储 null,null,但是如果使用 putIfAbsent ,只能存储同时不为null的映射

        map.forEach((s, o) -> System.out.println(s+":"+o)); // 遍历集合

        map.computeIfPresent("kitty", (key, val) -> val +"_"+ key); // 操作指定key的映射

        map.get("kitty");      

        map.computeIfAbsent("kitty", key -> "val" + key);  // 操作指定key的映射

        map.get("kitty");

 

© 著作权归作者所有

上一篇: Docx4j 添加页码
下一篇: For Update
learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
加载中

评论(0)

Java 8 中新的 Date 和 Time 类入门详解

这篇文章主要是java8中新的Date和Time API的实战。新的Date和Time类是java开发者社区千呼万唤始出来的。Java8 之前存在的Date类一直都受人诟病,很多人都会选择使用第三方的date库joda-time...

默默学习中
2016/05/04
781
0
30分钟入门Java8之默认方法和静态接口方法

30分钟入门Java8之默认方法和静态接口方法 作者:@JohnTsai 本文为作者原创,转载请注明出处:http://www.cnblogs.com/JohnTsai/p/5598036.html 30分钟入门Java8之默认方法和静态接口方法 前...

spinachgit
2018/01/12
79
0
java8的重要特性及其他,昨天答应的发java8╭(╯ε╰)╮

【注意】本文节选自是 DZone 指南 Java 生态系统的专题文章,作者Trisha Gee是Java资深工程师和布道者。在本文中,Trisha Gee阐述了Java 8的重要特性以及使用的原因,由OneAPM工程师翻译。 ...

默默学习中
2016/03/28
1.5K
9
spark2.x由浅入深深到底系列六之RDD 支持java8 lambda表达式

学习spark任何技术之前,请正确理解spark,可以参考:正确理解spark 我们在 http://7639240.blog.51cto.com/7629240/1966131 中已经知道了,一个scala函数其实就是java中的一个接口,对于jav...

tangweiqun
2017/09/20
0
0
OSC源创会之校园行第4期

源创会之开源校园行第4期~这次我们来到了潮州高校区~ 小伙伴么福利来咯、 开源是什么?git、gitlab、github 又是怎么?怎么使用?还有二师兄带来JAVA8干货!! 除了给同学们带来开源技术大...

文洁洁洁
2015/04/17
4.6K
18

没有更多内容

加载失败,请刷新页面

加载更多

这15个Vue指令,让你的项目开发爽到爆

受 AngularJS 的启发,Vue 内置了一些非常有用的指令(比如v-html 和 v-once等),每个指令都有自身的用途。完整的指令列表可以在这里查看. 这还没完,更棒的是可以开发自定义指令。Vue.js ...

李中凯
26分钟前
49
0
HTTP与HTTPS的区别

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以...

无名氏的程序员
32分钟前
45
0
如何在A4纸张尺寸页面中制作HTML页面?

是否可以使HTML页面的行为类似于MS Word中的A4大小的页面? 本质上,我希望能够在浏览器中显示HTML页面,并以A4尺寸页面的尺寸概述内容。 为了简单起见,我假设HTML页面仅包含文本(没有图像...

javail
40分钟前
28
0
工作流-变量

流程变量的作用: 用来传递业务参数(比如请假天数,请假原因等); 指定连线完成任务(同意和拒绝); 动态指定任务的办理人. 流程变量要用的表: act_ru_variable; -- 正在执行的流程变量表...

小小明1995
41分钟前
49
0
JVM解毒——类加载子系统

带着问题,尤其是面试问题的学习才是最高效的。加油,奥利给! 点赞+收藏 就学会系列,文章收录在 GitHub JavaEgg ,N线互联网开发必备技能兵器谱 直击面试 看你简历写得熟悉JVM,那你说说类...

大猿帅
51分钟前
37
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部