当前位置: 首页 > news >正文

java8新特新(二)

1.函数式接口

Java 语言设计者们投入了大量精力来思考如何使现有的函数友好地支持 Lambda。最终采取的方法是:增加函数式接口的概念。“函数式接口”是指仅仅只包含一个抽象方法,但是可以有多个非抽象方法(也就是上面提到的默认方法)的接口。 像这样的接口,可以被隐式转换为 lambda 表达式。java.lang.Runnablejava.util.concurrent.Callable 是函数式接口最典型的两个例子。Java 8 增加了一种特殊的注解@FunctionalInterface,但是这个注解通常不是必须的(某些情况建议使用),只要接口只包含一个抽象方法,虚拟机会自动判断该接口为函数式接口。一般建议在接口上使用@FunctionalInterface 注解进行声明,这样的话,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。

示例:

@FunctionalInterface
public interface Converter<F, T> {T convert(F from);
}
    // TODO 将数字字符串转换为整数类型Converter<String, Integer> converter = (from) -> Integer.valueOf(from);Integer converted = converter.convert("123");System.out.println(converted.getClass()); //class java.lang.Integer

2.方法和构造函数引用

java 8 允许您通过::关键字传递方法或构造函数的引用。 上面的示例显示了如何引用静态方法。 但我们也可以引用对象方法

class Something {String startsWith(String s) {return String.valueOf(s.charAt(0));}
}
Something something = new Something();
Converter<String, String> converter = something::startsWith;
String converted = converter.convert("Java");
System.out.println(converted);    // "J"

构造函数是如何使用::关键字来引用的,首先我们定义一个包含多个构造函数的简单类

class Person {String firstName;String lastName;Person() {}Person(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}
}

我们指定一个用来创建 Person 对象的对象工厂接口

interface PersonFactory<P extends Person> {P create(String firstName, String lastName);
}

这里我们使用构造函数引用来将他们关联起来,而不是手动实现一个完整的工厂

PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");

我们只需要使用 Person::new 来获取 Person 类构造函数的引用,Java 编译器会自动根据PersonFactory.create方法的参数类型来选择合适的构造函数

3.Lambda表达式作用域

3.1 访问局部变量

直接在 lambda 表达式中访问外部的局部变量

final int num = 1;
Converter<Integer, String> stringConverter =(from) -> String.valueOf(from + num);stringConverter.convert(2);     // 3

但是和匿名对象不同的是,这里的变量 num 可以不用声明为 final,该代码同样正确

int num = 1;
Converter<Integer, String> stringConverter =(from) -> String.valueOf(from + num);stringConverter.convert(2);     // 3

不过这里的 num 必须不可被后面的代码修改(即隐性的具有 final 的语义)

int num = 1;
Converter<Integer, String> stringConverter =(from) -> String.valueOf(from + num);
num = 3;//在lambda表达式中试图修改num同样是不允许的。

 3.2 访问字段和静态变量

与局部变量相比,我们在 lambda 表达式中对实例字段和静态变量都有读写访问权限。 该行为和匿名对象是一致的

class Lambda4 {static int outerStaticNum;int outerNum;void testScopes() {Converter<Integer, String> stringConverter1 = (from) -> {outerNum = 23;return String.valueOf(from);};Converter<Integer, String> stringConverter2 = (from) -> {outerStaticNum = 72;return String.valueOf(from);};}
}

3.3 访问默认接口方法

Formula 接口定义了一个默认方法sqrt,可以从包含匿名对象的每个 formula 实例访问该方法。 这不适用于 lambda 表达式

Formula formula = (a) -> sqrt(a * 100);


http://www.mrgr.cn/news/33928.html

相关文章:

  • AI学习指南深度学习篇-Adadelta的数学原理
  • Project Online 高级版部署方案
  • 7款国内AI搜索引擎大全网站
  • Kotlin Android 环境搭建
  • uniapp map设置高度为100%后,会拉伸父容器的高度
  • MateBook 16s 2023在Deepin下开启性能模式,调节风扇转速到最大,全网首发!
  • 返利机器人在电商返利系统中的负载均衡实现
  • 【C语言零基础入门篇 - 17】:排序算法
  • PHP isset() 和 empty() 区别
  • 【C++】继承(上)
  • 定了,东湖高新区下半年中高级职称申报时间
  • java日志框架之Log4j
  • Golang | Leetcode Golang题解之第430题扁平化多级双向链表
  • C++标准库双向链表 list 中的insert函数实现。
  • C++离线查询
  • Golang | Leetcode Golang题解之第429题N叉树的层序遍历
  • Codeforces Round 969 (Div. 1) C. Eri and Expanded Sets(线段树维护差分数组gcd+双指针+尺取)
  • git-repo系列教程(4) windows平台下安装git-repo客户端
  • Leetcode 每日一题:Diameter of Binary Tree
  • AI教你学Python 第18天 : 线性数据结构