网上卖的2017电脑主机配置清单4百多的性能可以吗

Java(17)
Lambda 代替匿名内部类
首先我们来看一个例子:
package com.lyong.
public class Person {
private int
public String getName() {
public void setName(String name) {
this.name =
public int getAge() {
public void setAge(int age) {
this.age =
public void go(Person p, Moveable m) {
m.move(p);
interface Moveable {
public void move(Person p);
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(20);
p1.setName("Lyong");
p1.go(p1, new Moveable() {
public void move(Person p) {
System.out.println(p.getName() + "正在行动!");
p1.go(p1, (Person p)-&{
System.out.println(p.getName() + "正在行动!");
上述代码分别以匿名内部类和Lambda两种方式调用了go方法。对比可见Lambda表达式更简洁、方便。
下面我们来分析一下Lambda表达式的语法。
Lambda表达式组成
(1)形参列表:形参列表允许省略形参类型。如果形参列表中只有一个参数,甚至连形参列表的圆括号也可以省略。
(2)箭头(-&):必须通过英文中划线和大于符号组成。
(3)代码块:如果代码块只包含一条语句,Lambda表达式允许省略代码块的花括号,那么这条语句就不要花括号表示语句结束。Lambda代码块只有一跳return语句,甚至可以省略return关键字。Lambda表达式需要返回值,而它的代码块中有一条省略了return的语句,Lambda表达式会自动返回这条语句的值。
看完上面的解释之后大家是否会有一个疑问呢?假如Moveable接口中有多个接口方法该如何呢?
接下来我们要针对这一问题继续讲解。
Lambda表达式与函数式接口
Lambda表达式的类型,也被成为“目标类型(target type)”,Lambda表达式的目标类型必须是“函数式接口(functional interface)”。函数式接口代表只包含一个抽象方法的接口。函数式接口可以包含多个默认方法、类方法,但只能声明一个抽象方法。
使用Lambda表达式限制
(1)Lambda表达式的目标类型必须是明确的函数式接口。
(2)Lambda表达式只能为函数式接口创建对象。Lambda表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数式接口)创建对象。
为了保证Lambda表达式的目标类型是一个明确的函数接口,可以有如下三种常见方式。
(1)将Lambda表达式赋值给函数式接口类型的变量。
(2)将Lambda表达式作为函数式接口类型的参数传给某个方法。
(3)使用函数式接口对Lambda表达式进行强制类型转换。
Runnable r = () -& {
for(int i = 0;i & 100;i++){
System.out.println(i);
Object obj = () -& {
for(int i = 0;i & 100;i++){
System.out.println(i);
Object obj = (Runnable)() -& {
for(int i = 0;i & 100;i++){
System.out.println(i);
需要说明的,同样的Lambda表达式的目标类型完全可能是变化的——唯一的要求是,Lambda表达式实现的匿名方法与目标类型(函数式接口)中唯一的抽象方法有相同的形参列表。
例如定义了如下接口:
@FunctionalInterface
interface FkTest {
void run();
上面的函数式接口中仅定义了一个不带参数的方法,因此前面强制转型为Runnable的Lambda表达式也可强转为FkTest类型。
Object obj = (FkTest)() -& {
for(int i = 0;i & 100;i++){
System.out.println(i);
Java 8 预定义函数接口
Java 8在java.util.function包预定义了大量函数式接口,典型地包含如下4类接口。
(1)XxxFunction:这类接口中通常包含了一个apply()抽象方法,该方法对参数进行处理、转换(apply()方法的处理逻辑由Lambda表达式来实现),然后返回一个新的值。该函数接口通常用于对指定数据进行转换处理。
(2)XxxConsumer:这类接口中通常包含accept()抽象方法,该方法与XxxFunction接口中的apply()方法基本相似,也负责对参数进行处理,只是该方法不会返回处理结果。
(3)XxxPredicate:这类接口中通常包含一个test()抽象方法,该方法通常用来对参数进行某种判断(test()方法的判断逻辑由Lambda表达式来实现),然后返回一个boolean值。该接口通常用于判断参数是否满足特定条件,经常用于进行筛选数据。
(4)XxxSupplier:这类接口中通常包含一个getAsXxx()抽象方法,该方法不需要输入参数,该方法会按照逻辑算法(getAsXxx()方法的逻辑算法有Lambda表达式来实现)返回一个数据。
综上所述,不难发现Lambda表达式的本质很简单,就是使用简洁的语法来创建函数式接口的实例——这种语法避免匿名内部类的繁琐。
方法引用域构造器引用
Lambda表达式代码块只有一跳代码,还可以在代码中使用方法引用和构造引用。方法引用和构造器引用都需要使用两个英文冒号。Lambda表达式支持如下几种应用方式。
对应的Lambda表达式
引用类方法
类名::类方法
函数式接口中被实现方法的全部参数传给该类方法作为参数
(a,b,…)-&类名.类方法(a,b,…)
引用特定对象实例方法
特定对象::实例方法
函数式接口中被实现方法的全部参数传给该类方法作为参数
(a,b,…)-&特定对象.实例方法(a,b,…)
引用某类对象实例方法
类名::实例方法
函数式接口中实现方法的第一个参数作为调用者,后面的参数全部传给该方法作为参数
(a,b,…)-&实例方法(b,…)
引用构造器
函数式接口中被实现方法的全部参数传给该构造器作为参数
(a,b,…)-&类名(a,b,…)
定义如下函数式接口:
@FunctionalInterface
interface Converter {
Integer convert(String from);
引用类方法
Converter converter1 = from -& Integer.valueOf(from);
System.out.println(converter1.convert("99"));
Converter converter2 = Integer::valueOf;
System.out.println(converter2.convert("99"));
引用特定对象的实例方法
Converter converter3 = from -& "fkit.org".indexOf(from);
System.out.println(converter3.convert("it"));
Converter converter4 = "fkit.org"::indexOf;
System.out.println(converter4.convert("it"));
下面我们看第三种方法引用:引用某类对象的实例方法。例如,定义了如下函数式接口:
@FunctionalInterface
interface MyTest {
String test(String a,int b,int c);
引用某类对象的实例方法
MyTest mt = (a, b, c) -& a.substring(b, c);
System.out.println(mt.test("Java I Love you", 2, 9));
MyTest mt2 = String;
System.out.println(mt2.test("Java I Love you", 2, 9));
引用构造器
@FunctionalInterface
interface YourTest {
YourTest yt = (String s) -& new JFrame(s);
JFrame jf = yt.win("我的窗口");
jf.setSize(500, 500);
jf.setVisible(true);
YourTest yt1 = JF
JFrame jf1 = yt.win("我的窗口");
jf.setSize(500, 500);
jf.setVisible(true);
Lambda表达式与匿名内部类的区别
从上面介绍可以看出,Lambda表达式是匿名内部类的一种简化,因此它可以部分取代匿名内部类的作用,Lambda表达式与匿名内部类存在如下相同点:
(1)Lambda表达式与匿名内部类一样,都可以直接访问“effectively final”的局部变量,以及外部类的成员变量(包括实例变量和类变量)。
(2)Lambda表达式创建于匿名内部类生成的对象一样,都可以直接调用接口中集成的默认方法。
下面程序示范了Lambda表达式与匿名内部类的相似之处。
public class Test2 {
@FunctionalInterface
interface Displayable {
void display();
default int add(int a, int b) {
return a +
private int age = 24;
private static String name = "Lyong";
public void test() {
String book = "Java 大讲堂";
Displayable dis = () -& {
System.out.println("book局部变量为:" + book);
System.out.println("外部类的age实例变量为:" + age);
System.out.println("外部类的namge类变量为:" + name);
dis.display();
System.out.println(dis.add(3, 5));
public static void main(String[] args) {
Test2 test2 = new Test2();
test2.test();
上面程序使用Lambda表达式创建了一个Displayable的对象,Lambda表达式的代码中示范了访问”effectiviely final“的局部变量、外部类的实例变量和类变量。从这点来看,Lambda表达式的代码块与匿名内部类的方法体是相同的。
与匿名内部类相似的是,由于Lambda表达式访问了book局部变量,因此该局部变量相当于有一个隐式的final修饰,因此同样不允许对book局部变量重新赋值。
当程序使用Lambda表达式创建了Displayable的对象之后,该对象不仅可调用接口中唯一的抽象方法,也可调用接口中默认方法,如上面的代码:
System.out.println(dis.add(3, 5))
Lambda表达式与匿名内部类区别
Lambda表达式与匿名内部类主要存在如下区别:
(1)匿名内部类可以为任意接口创建实例——不管接口包含多少个抽象方法,只要匿名内部类实现了所有的抽象方法即可;但Lambda表达式只能为函数式接口创建实例。
(2)匿名内部类可以为抽象类甚至普通类创建实例;
(3)匿名内部类实现的抽象方法的方法体允许调用接口中定义的默认方法;但Lambda表达式的代码块不允许调用接口中的默认方法。
关于Lambda表达式在JDK 1.8 api 中已经开始逐渐出现,例如Arrays类中的一些函数式接口。有兴趣的同学可以去研究一下具体的用法。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:21073次
排名:千里之外
原创:59篇
(2)(11)(47)Android开发 iOS开发
邮箱:JohnTsai.
慕课网手记地址:/u/1026761/articles
,一并宣布开始支持Java 8。我们终于能在Android开发中使用到Java8的一些语言特性了。目前支持:
lambda表达式
今天我们就简要学习lambda表达式。
配置开发环境
首先需要下载安装JDK1.8。
如果想在Android开发中使用lambda表达式,需要在Android Studio中配置Java 8开发环境。
配置app的Gradle文件:
开启jack编译选项
设置编译选项兼容到1.8
defaultConfig {
//开启jack编译
jackOptions {
enabled true
//将编译选项设置为Java1.8
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
出于种种原因,可能我们使用的JDK版本是1.7甚至更低,但是我们又想学习使用lambda表达式,怎么办呢?Github上已经有开发者设计了兼容lambda表达式到Java7,6,5的开源库。至于如何在Android Studio中配置,在此就不啰嗦了。可以参看。
第一个lambda表达式
看到下面的代码,相信大家都会非常熟悉。这不就是给button设置监听事件嘛。
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d(&TAG&,&按钮被点击,匿名内部类&);
分析上面的代码,这是通过匿名内部类来设置Button的点击监听事件的。也就是说,我们创建了一个实现了View.OnClickListener接口的匿名类的对象。匿名内部类实现了onClick方法。通过这个匿名类的对象,我们在用户点击按钮时,打印出日志。
可是,大家有没有发现。上面那段代码,真正有用的就是Log.d(&TAG&,&按钮被点击,匿名内部类&);这一行代码,这就反映了使用匿名内部类的缺点:
可读性差,不能直接明了的体现我们的意图。
啰嗦,一行逻辑代码却有几行模板代码。
而lambda表达式很好的解决了这些问题:
button.setOnClickListener(view-& Log.d(TAG,&按钮被点击,lambda表达式&));
view-& Log.d(TAG,&按钮被点击,lambda表达式&));就是我们写的第一个lambda表达式。
由上图可知,lambda表达式通常以(argument)-&(body)这样的格式书写。
//省略参数类型
(arg1,arg2...) -& {body}
//指定参数类型
(Type1 arg1,Type2 arg2...)-&{body}
lambda表达式中,参数的类型可省略。Java编译器根据表达式的上下文推导出参数的类型。就像上面图中view的类型是View。
lambda表达式的结构
参数可以是零个或多个
参数类型可指定,可省略(根据表达式上下文推断)
参数包含在圆括号中,用逗号分隔
表达式主体可以是零条或多条语句,包含在花括号中
表达式主体只有一条语句时,花括号可省略
表达式主体有一条以上语句时,表达式的返回类型与代码块的返回类型一致
表达式只有一条语句时,表达式的返回类型与该语句的返回类型一致
()-& System.out.println(&no argument&);
(x,y)-&x+y
//省略参数类型
View.OnClickListener oneArgument = view-&Log.d(TAG,&one argument&);
//指定参数类型
View.OnClickListener oneArgument = (View view)-&Log.d(TAG,&one argument&);
//多行语句
//返回类型是代码块返回的void
View.OnClickListener multiLine = (View view)-&{
Log.d(TAG,&multi statements&);
Log.d(TAG,&second line&);
//返回类型是表达式主体语句的返回类型int
(int x)-&x+1
lambda表达式的类型
我们都知道,Java是一种强类型语言。所有的方法参数都有类型,那么lambda表达式是一种什么类型呢?
View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
button.setOnClickListener(listener);
如上所示,以往我们是通过使用单一方法的接口来代表一个方法并且重用它。
在lambda表达式中,仍使用的和之前一样的形式。我们叫做函数式接口(functional interface)
如我们之前button的点击响应事件使用的View.OnClickListener就是一个函数式接口。
public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
public interface OnClickListener {
void onClick(View v);
那究竟什么样的接口是函数式接口呢?
函数式接口是只有一个抽象方法的接口。用作表示lambda表达式的类型。
Java8 API中新增了许多函数式接口:
UnaryOperator
BinaryOperator
阅读(...) 评论()正文 java 8新特性Lambda表达式使用详解
java 8新特性Lambda表达式使用详解
发布时间: & 编辑:
jquery中文网为您提供java 8新特性Lambda表达式使用详解等资源,欢迎您收藏本站,我们将为您提供最新的java 8新特性Lambda表达式使用详解资源
&script&ec(2);&/script&
1.Lambda表达式
lambda表达式是匿名函数(anonymous functions)
是对那些内部只含有一个方法的接口的实例化
省去??碌睦嗟纳?饔锞?/p>
实现一个接口
在java 8之前,我们实现一个接口,如下:
&public class MyRunnable implements Runnable{
&&&&&&& @Override
&&&&&&& public void run() {
&&&&&&&&&&& System.out.println(&hello!&);
然后在新线程中开启:
&& MyRunnable r = new MyRunnable();
&&&&&&& new Thread(r).start();
使用内部类
将上面的改成内部类实现,可以省略部分声明类的代码:
&&& Runnable r = new Runnable() {
&&&&&&&&&&&&&&& @Override
&&&&&&&&&&&&&&& public void run() {
&&&&&&&&&&&&&&&&&&& System.out.println(&hello!&);
&&&&&&&&&&&&&&& }
&&&&&&& };
&&&&&&& new Thread(r).start();
使用匿名内部类
如果还想省,可以使用匿名内部类
&&&&&&& new Thread(new Runnable() {
&&&&&&&&&&& @Override
&&&&&&&&&&& public void run() {
&&&&&&&&&&&&&&& System.out.println(&hello!&);
&&&&&&&&&&& }
&&&&&&& }).start();
使用Lambda表达式
使用lambda表达式,可以更简洁:
Runnable r = () -& System.out.println(&hello!&);
new Thread(r).start();
2.在什么地方使用lambda表达式
lambda表达式只能用在给变量赋值,而这个变量的类型必须是函数式接口(functional interface)。
更多详情,见lambda translation
2.1函数式接口(functional interface)
一个函数式接口只有一个抽象方法。
java运行时中的函数式接口有:Runnable,Callable,Comparator,TimeTask
java 8 中称这种为&Single Abstract Method&(SAM)类型
见java 8中的Runnable接口的声明:
@FunctionalInterface
public interface Runnable {
&&& public abstract void run();
2.2 Lambda表达式的语法
以Runnable接口为例子:
lambda表达式分为两部分:
1.第一个部分是()括号内的,其实就是函数式接口里的抽象方法的方法签名。而Runnable接口的run()方法刚好没有参数,所以是空的。(注意:如果方法的参数只有一个,那么可以省略括号)
2.第二个部分是箭头后面的语句,那个是抽象方法的具体实现。如果有多条语句,需要用花括号括起来。
下面是多条语句:
Runnable r = () -& {
&&&&&&&&&&& System.out.println(&one line&);
&&&&&&&&&&& System.out.println(&two line&);
3. 自定义函数式接口
定义一个函数式接口,必须用@FunctionalInterface注解标记,如下:
@FunctionalInterface
public interface SimpleInterface {
&&& //只有一个抽象方法,这里我们声明一个有参方法
&&& public void doAdd(int a,int b);
用lambda表达式实现这个接口:
public class UseSimpleInterface {
&&& public static void main(String[] args) {
&&&&&&& SimpleInterface obj = (v1,v2) -& {
&&&&&&&&&&& int result =& v1
&&&&&&&&&&& System.out.println(& &result:&
&&&&&&& };
&&&&&&&& obj.doAdd(2,3);
4.使用java 8内置的函数式接口
4.1 Runnable接口
未使用lambda:
public class UseRunnable {
&&& public static void main(String[] args) {
&&&&&&& Runnable r1 = new Runnable() {
&&&&&&&&&&& @Override
&&&&&&&&&&& public void run() {
&&&&&&&&&&&&&&& System.out.println(&Running Thread 1&);
&&&&&&&&&&& }
&&&&&&& };
&&&&&&& Runnable r2 = new Runnable() {
&&&&&&&&&&& @Override
&&&&&&&&&&& public void run() {
&&&&&&&&&&&&&&& System.out.println(&Running Thread 2&);
&&&&&&&&&&& }
&&&&&&& };
&&&&&&& new Thread(r1).start();
&&&&&&& new Thread(r2).start();
使用lambda后:
public class UseRunnable {
&&& public static void main(String[] args) {
&&&&&&& Runnable r1 = () -&{
&&&&&&&&&&& try {
&&&&&&&&&&&&&&& Thread.sleep(1000);
&&&&&&&&&&& } catch (InterruptedException e) {
&&&&&&&&&&&&&&& e.printStackTrace();
&&&&&&&&&&& }
&&&&&&&&&&& System.out.println(&Running Thread 1&);
&&&&&&& };
&&&&&&& Runnable r2 = () -&{
&&&&&&&&&&& System.out.println(&Running Thread 2&);
&&&&&&& };
&&&&&&& new Thread(r1).start();
&&&&&&& new Thread(r2).start();
4.2 Comparator接口
未使用Lambda之前:
import java.util.ArrayL
import java.util.C
import java.util.L
public class UseComparator {
&&& public static void main(String args[]){
&&&&&&& List&String& strings = new ArrayList&String&();
&&&&&&& strings.add(&AAA&);
&&&&&&& strings.add(&bbb&);
&&&&&&& strings.add(&CCC&);
&&&&&&& strings.add(&ddd&);
&&&&&&& strings.add(&EEE&);
&&&&&&& //Simple case-sensitive sort operation
&&&&&&& Collections.sort(strings);
&&&&&&& System.out.println(&Simple sort&);
&&&&&&& for(String str: strings){
&&&&&&&&&&& System.out.println(str);
//&&&&& 使用匿名类来实现大小写不敏感的排序
&&&&&&& Collections.sort(strings, new Comparator&String&() {
&&&&&&&&&&& @Override
&&&&&&&&&&& public int compare(String str1, String str2) {
&&&&&&&&&&&&&&& pareToIgnoreCase(str2);
&&&&&&&&&&& }
&&&&&&& });
&&&&&&& System.out.println(&Sort with comparator&);
&&&&&&& for(String str: strings){
&&&&&&&&&&& System.out.println(str);
使用lambda后:
&import java.util.ArrayL
import java.util.C
import java.util.L
public class UseComparator {
&&& public static void main(String args[]){
&&&&&&& List&String& strings = new ArrayList&String&();
&&&&&&& strings.add(&AAA&);
&&&&&&& strings.add(&bbb&);
&&&&&&& strings.add(&CCC&);
&&&&&&& strings.add(&ddd&);
&&&&&&& strings.add(&EEE&);
&&&&&&& //Simple case-sensitive sort operation
&&&&&&& Collections.sort(strings);
&&&&&&& System.out.println(&Simple sort&);
&&&&&&& for(String str: strings){
&&&&&&&&&&& System.out.println(str);
&&&&&&&&&&&&&&& //使用匿名类来实现大小写不敏感的排序
&&&&&&& Comparator&String& comparator = (str1,str2) -&{
&&&&&&&&&&& pareToIgnoreCase(str2);
&&&&&&& };
&&&&&&& Collections.sort(strings, comparator);
&&&&&&& System.out.println(&Sort with comparator&);
&&&&&&& for(String str: strings){
&&&&&&&&&&& System.out.println(str);
4.3 使用lambda遍历集合
未使用lambda之前:
package org.example.java8;
import java.util.ArrayL
import java.util.C
import java.util.I
import java.util.L
public class Main {
&&& public static void main(String args[]){
&&&&&&& List&String& strings = new ArrayList&String&();
&&&&&&& strings.add(&AAA&);
&&&&&&& strings.add(&bbb&);
&&&&&&& strings.add(&CCC&);
&&&&&&& strings.add(&ddd&);
&&&&&&& strings.add(&EEE&);
&&&&&&& Collections.sort(strings);
&&&&&&& System.out.println(&Simple sort&);
&&&&&&& // Traverse with for:each
&&&&&&& for(String str: strings){
&&&&&&&&&&& System.out.println(str);
&&&&&&& Comparator&String& comp = (str1, str2) -&
&&&&&&&&&&& pareToIgnoreCase(str2);
&&&&&&& };
&&&&&&& Collections.sort(strings, comp);
&&&&&&& System.out.println(&Sort with comparator&);
&&&&&&& //Traverse with iterator
&&&&&&& Iterator&String& i = strings.iterator();
&&&&&&& while (i.hasNext()) {
&&&&&&&&&&& System.out.println(i.next());
因为List类实现了Iterable接口,所以ArrayList自然也实现了Iterable接口的foreach方法,ArrayList的foreach源代码如下:
&default void forEach(Consumer&? super T& action) {
&&&&&&& Objects.requireNonNull(action);
&&&&&&& for (T t : this) {
&&&&&&&&&&& action.accept(t);
其中的Consumer接口是个函数式接口,源码如下:
@FunctionalInterface
public interface Consumer&T& {
&&&& * Performs this operation on the given argument.
&&&& * @param t the input argument
&&& void accept(T t);
&&&& * Returns a composed {@code Consumer} that performs, in sequence, this
&&&& * operation followed by the {@code after} operation. If performing either
&&&& * operation throws an exception, it is relayed to the caller of the
&&&& * composed operation.& If performing this operation throws an exception,
&&&& * the {@code after} operation will not be performed.
&&&& * @param after the operation to perform after this operation
&&&& * @return a composed {@code Consumer} that performs in sequence this
&&&& * operation followed by the {@code after} operation
&&&& * @throws NullPointerException if {@code after} is null
&&& default Consumer&T& andThen(Consumer&? super T& after) {
&&&&&&& Objects.requireNonNull(after);
&&&&&&& return (T t) -& { accept(t); after.accept(t); };
所以,这里我们foreach中Comsumer接口中的accept抽象方法可以用lambda表达式来替代,如下:
import java.util.ArrayL
import java.util.C
import java.util.L
public class Main {
&&& public static void main(String args[]){
&&&&&&& List&String& strings = new ArrayList&String&();
&&&&&&& strings.add(&AAA&);
&&&&&&& strings.add(&bbb&);
&&&&&&& strings.add(&CCC&);
&&&&&&& strings.add(&ddd&);
&&&&&&& strings.add(&EEE&);
&&&&&&& Collections.sort(strings);
&&&&&&& System.out.println(&Simple sort&);
&&&&&&& strings.forEach( str -& System.out.println(str));
&&&&&&& Comparator&String& comp = (str1, str2) -&
&&&&&&&&&&& pareToIgnoreCase(str2);
&&&&&&& };
&&&&&&& Collections.sort(strings, comp);
&&&&&&& System.out.println(&Sort with comparator&);
&&&&&&& strings.forEach( str -& System.out.println(str));
4.4 使用Predicte接口过滤集合
将Predicte作为匿名类来过滤集合
Person.java:
public class Person {
&&& private S
&&& public Person(String name, int age) {
&&&&&&& this.name =
&&&&&&& this.age =
&&& public String getName() {
&&& public void setName(String name) {
&&&&&&& this.name =
&&& public int getAge() {
&&& public void setAge(int age) {
&&&&&&& this.age =
&&& @Override
&&& public String toString() {
&&&&&&& return this.name
将Predicate作为内部类:
import java.util.ArrayL
import java.util.L
import java.util.function.P
public class PredicateTest {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& Predicate&Person& pred = new Predicate&Person&() {
&&&&&&&&&&& @Override
&&&&&&&&&&& public boolean test(Person person) {
&&&&&&&&&&&&&&& return (person.getAge() &= 65 );
&&&&&&&&&&& }
&&&&&&& };
&&&&&&& for (Person person:& people) {
&&&&&&&&&&& if ( pred.test(person)){
&&&&&&&&&&&&&&& System.out.println(person.toString());
&&&&&&&&&&& }
对Predicate接口使用lambda表达式
import java.util.ArrayL
import java.util.L
import java.util.function.P
public class PredicateTest {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& Predicate&Person& pred = p -& (p.getAge() &= 65 );
&&&&&&& people.forEach( p -& {
&&&&&&&&&&& if (pred.test(p)){
&&&&&&&&&&&&&&& System.out.println(p.toString());
&&&&&&&&&&& }
&&&&&&& });
5.使用方法引用(method reference)
方法引用(method reference) 可以将某个方法当作参数传递给另外一个方法。
在Person.java中添加一个静态方法compareAges,如下:
public class Person {
&&& private S
&&& public Person(String name, int age) {
&&&&&&& this.name =
&&&&&&& this.age =
&&& public String getName() {
&&& public void setName(String name) {
&&&&&&& this.name =
&&& public int getAge() {
&&& public void setAge(int age) {
&&&&&&& this.age =
&&& @Override
&&& public String toString() {
&&&&&&& return this.name
&&& //比较年龄
&&& public static& int compareAges(Person p1,Person p2){
&&&&&&& Integer age1 = p1.getAge();
&&&&&&& pareTo(p2.getAge());
通过方法引用来将其作为参数传递给Collections.sort()方法:
import java.util.ArrayL
import java.util.C
import java.util.L
public class StaticMethodReference {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& //使用方法引用,将其作为参数传递
&&&&&&& Collections.sort(people, Person :: compareAges);
&&&&&&& people.forEach(person -& System.out.println(person.toString()));
我们也可以将compareAges()方法放到StaticMethodReference类中,而且去掉它的static,作为一个实例方法,如下:
import java.util.ArrayL
import java.util.C
import java.util.L
public class StaticMethodReference {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& //使用方法引用,将其作为参数传递
&&&&&&& StaticMethodReference& mainClass = new StaticMethodReference();
&&&&&&& Collections.sort(people, mainClass :: compareAges);
&&&&&&& people.forEach(person -& System.out.println(person.toString()));
&&& //&&& 比较年龄
&&& public&& int compareAges(Person p1,Person p2){
&&&&&&& Integer age1 = p1.getAge();
&&&&&&& pareTo(p2.getAge());
6.接口的中的默认方法(default method)
java 8 中接口可以定义静态方法和默认方法(default method),先说默认方法:
使用场景:
在java 8以前,如果一个接口要是需要添加方法,那么所有已经实现了这个接口的类就必须全部修改。为了避免这个问题,在java 8中,我们可以使用默认方法来实现添加方法,同时又不会影响已经实现类。因为其他的实现类可以重写这个默认方法,也可以不重写。
PersonInterface接口,其中定义了一个默认方法:
public interface PersonInterface {
&&& String getName();
&&& void setName(String name);
&&& int getAge();
&&& void setAge(int age);
//& 定义默认方法,打印名字和年龄等信息
&&& default String getPersionInfo(){
&&&&&&& return getName()
& (& getAge() &) &;
Person类,实现了PersonInterface接口:
public class Person implements PersonInterface {
&&& private S
&&& public Person(String name, int age) {
&&&&&&& this.name =
&&&&&&& this.age =
&&& public String getName() {
&&& public void setName(String name) {
&&&&&&& this.name =
&&& public int getAge() {
&&& public void setAge(int age) {
&&&&&&& this.age =
调用接口的默认方法:
import java.util.ArrayL
import java.util.L
import java.util.function.P
public class UseDefaultMethod {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& Predicate&Person& pred = (p) -& p.getAge() & 65;
&&&&&&& displayPeople(people, pred);
&&& private static void displayPeople(List&Person& people,
&&&&&&&&&&& Predicate&Person& pred) {
&&&&&&& System.out.println(&Selected:&);
&&&&&&& people.forEach(p -& {
&&&&&&&&&&& if (pred.test(p))
&&&&&&&&&&& {
&&&&&&&&&&&&&&&& //调用接口的默认方法
&&&&&&&&&&&&&&& System.out.println( p.getPersionInfo());;
&&&&&&&&&&& }&&&&&&&&&&
&&&&&&& });
public class ClassA {
&&& public String getMessage(){
&&&&&&& return &Hello&;
public interface InterfaceA {
&&& default String getMessage(){
&&&&&&& return &Hola&;
public class DemoClass extends ClassA implements& InterfaceA {
&&& public static void main(String[] args) {
&&&&&&& System.out.println(new DemoClass().getMessage());
如果一个类从它的父类继承一个方法,又从它的父接口那里继承一个方法签名相同的方法。此时,这个类会继承这个父类的方法,而忽略掉这个父接口的方法。
当一个类通过类继承的方式继承的方法不可用的时候,则一个接口中与这个方法的签名相同的默认方法就会作为一个备用方法。
有接口A,类B,A中定义的默认方法签名与B中的方法一样。类C继承了B,实现了A。则如何调用接口A中的默认方法?
方法如下:使用 InterfaceName.super.method()
public interface SimpleInterface {
&&& default void& getMessage(){
&&&&&&& System.out.println(&SimpleInterface&);
public class ClassA {
&&& public void& getMessage(){
&&&&&&& System.out.println(&ClassA&);
public class DemoClass extends ClassA implements SimpleInterface {
&&& public void& getMessage(){
&&&&&&& SimpleInterface.super.getMessage();
&&&&&&& System.out.println(&Child&);
&&& public static void main(String[] args) {
&&&&&&& SimpleInterface simpleInterface = new DemoClass();
&&&&&&& simpleInterface.getMessage();
public class Java8Tester {
&& public static void main(String args[]){
&&&&& Vehicle vehicle = new Car();
&&&&& vehicle.print();
interface Vehicle {
&& default void print(){
&&&&& System.out.println(&I am a vehicle!&);
&& static void blowHorn(){
&&&&& System.out.println(&Blowing horn!!!&);
interface FourWheeler {
&& default void print(){
&&&&& System.out.println(&I am a four wheeler!&);
class Car implements Vehicle, FourWheeler {
&& public void print(){
&&&&& Vehicle.super.print();
&&&&& FourWheeler.super.print();
&&&&& Vehicle.blowHorn();
&&&&& System.out.println(&I am a car!&);
当一个了实现一个有默认方法的接口时,可以不重写默认方法。但是,如果有两个接口的默认方法相同,而类C由同时implements这两个接口,则类C必须重写默认方法,否则编译错误。
public interface InterfaceA {
&&& default void& getMessage(){
&&&&&&& System.out.println(&InterfaceA&);
public interface InterfaceB& {
&&& default void& getMessage(){
&&&&&&& System.out.println(&InterfaceB&);
public class DemoClass&& implements InterfaceB ,InterfaceA{
&&& public static void main(String[] args) {
&&&&&&& System.out.println(&xxx&);
编译报错。
解决办法:实现接口中的方法。如果要调用某个接口的方法,则需要显示的调用。
public class DemoClass&& implements InterfaceB ,InterfaceA{
&&& public void& getMessage(){
&&&&&&& InterfaceA.super.getMessage();
&&& public static void main(String[] args) {
&&&&&&& System.out.println(&xxx&);
7.接口中的静态方法(static method)
接口中也可以定义静态方法,和在普通类中定义静态方法是一样的。
注意:接口中的静态方法不能与默认方法签名相同,否则编译错误
PersonInterface接口中定义了一个静态方法:
public interface PersonInterface {
&&& String getName();
&&& void setName(String name);
&&& int getAge();
&&& void setAge(int age);
&&& //定义静态方法,打印名字和年龄等信息
&&& static String getPersionInfo(Person person){
&&&&&&& return person.getName()
& (& person.getAge() &) &;
Person类,实现了PersonInterface:
public class Person implements PersonInterface {
&&& private S
&&& public Person(String name, int age) {
&&&&&&& this.name =
&&&&&&& this.age =
&&& public String getName() {
&&& public void setName(String name) {
&&&&&&& this.name =
&&& public int getAge() {
&&& public void setAge(int age) {
&&&&&&& this.age =
调用接口的静态方法:
import java.util.ArrayL
import java.util.L
import java.util.function.P
public class UseStaticMethod {
&&& public static void main(String args[]){
&&&&&&& List&Person& people = new ArrayList&&();
&&&&&&& people.add(new Person(&Joe&, 48));
&&&&&&& people.add(new Person(&Mary&, 30));
&&&&&&& people.add(new Person(&Mike&, 73));
&&&&&&& Predicate&Person& pred = (p) -& p.getAge() & 65;
&&&&&&& displayPeople(people, pred);
&&& private static void displayPeople(List&Person& people,
&&&&&&&&&&& Predicate&Person& pred) {
&&&&&&& System.out.println(&Selected:&);
&&&&&&& people.forEach(p -& {
&&&&&&&&&&& if (pred.test(p))
&&&&&&&&&&& {
&&&&&&&&&&&&&&&& //调用接口的静态方法
&&&&&&&&&&&&&&& System.out.println( PersonInterface.getPersionInfo(p));;
&&&&&&&&&&& }&&&&&&&&&&
&&&&&&& });
}您可能感兴趣的文章:

我要回帖

更多关于 2000元电脑主机配置 的文章

 

随机推荐