栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java--接口,lambda表达式与内部类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java--接口,lambda表达式与内部类

杂项
1.接口
// 一个示例。接口中的所有方法都自动是public方法。
// 最新的Comparable支持泛型,可以避免装拆箱
public interface Comparable
{
	int compareTo(Object other);
}

class Employee implements Comparable
{
	public int compareTo(Object otherObject)
	{
		Employee other = (Employee)otherObject;
		return Double.compare(salary, other.salary);
	}
}
接口不会有实例字段。
接口可包含常量。
接口中的字段总是public static final。
2.继承
java中每个类只能有一个超类,但却可以实现多个接口。
class Employee implements Cloneable, Comparable
接口使用上类似抽象基类,但绕开了超类只能有一个的限制。
2.静态和私有方法
接口支持静态方法,私有方法。
3.默认方法
可以为接口方法提供一个默认实现,必须用default修饰符标记这样的一个方法。
public interface Comparable
{
	default int compareTo(T other)
	{
		return 0;
	}
}
4.类优先
类A派生自类B,派生自接口C。
B,C包含签名一致方法,类A中采用B的。
5.接口与回调
6.常用接口示例
public interface Comparator
{
	int compare(T first, T second);
}

class LengthComparator implements Comparator
{
	public int compare(String first, String second)
	{
		return first.length() - second.length();
	}
}

String[] friends = {"Peter", "Paul", "Mary"};
Arrays.sort(friends, new LengthComparator());
Object提供了clone方法的默认实现,Cloneable接口是java提供的少数标记接口之一。
Comparable等接口的通常用途是确保一个类实现一个或一组特定的方法。标记接口不包含任何方法,
它唯一的作用就是允许在类型查询中使用instanceof。
if(obj instanceof Cloneable)

// 依旧浅拷贝
class Employee implements Cloneable
{
	public Employee clone() throws CloneNotSupportedException
	{
		return (Employee)super.clone();
	}
	...
}

// 深拷贝
class Employee implements Cloneable
{
	...
	public Employee clone() throws CloneNotSupportedException
	{
		Employee cloned = (Employee)super.clone();
		cloned.hireDay = (Date)hireDay.clone();
		return cloned;
	}
}
如果在一个对象上调clone,但此对象的类没实现Cloneable接口,
Object类的clone方法会抛出一个CloneNotSupportedException。
lambda表达式
lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。
lambda表达式就是一个代码块,及必须传入代码的变量规范。
// 一个lambda示例
(String first, String second) ->
{
	if(first.length() < second.length())
	{
		return -1;
	}
	else if(first.length() > second.length())
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
lambda表达式的返回类型总是会由上下文推导得出。
- 函数式接口
前面讨论过,java中有很多封装代码块的接口。
lambda表达式与这些接口是兼容的。
对于只有一个抽象方法的接口,需要这种接口的对象时,可以提供一个lambda表达式。
这种接口称为函数式接口。

java没有函数类型,lambda表达式不可赋值给Object变量。
java api在java.util.function包中定义了很多非常通用的函数式接口。
其中一个接口BiFunction描述了参数类型为T和U且返回类型为R的函数。
BiFunction comp = (first, second)->first.length() - second.length();
想要用lambda表达式做某些处理,要谨记表达式的用途,为它建立一个特定的函数式接口。
public interface Predicate
{
	boolean test(T t);
}

public interface Supplier
{
	T get();
}
- 方法引用
var timer = new Timer(1000, System.out::println);
表达式System.out::println是一个方法引用,它指示编译器生成一个函数式接口的实例。
覆盖这个接口的抽象方法来调用给定的方法。
在这个例子中,会生成一个ActionListener,
它的actionPerformed(ActionEvent e)方法要调用System.out.println(e)。
Arrays.sort(strings, String::compareToIgnoreCase);
要用::运算符分隔方法名与对象或类名,主要有三种情况:
a.object::instanceMethod,
对于System.out::println,等价于x->System.out.println(x)
b.Class::instanceMethod
String::compareToIgnoreCase等同于(x, y)->x.compareToIgnoreCase(y)
c.Class::staticMethod
Math::pow等价于(x, y)->Math.pow(x, y)
separator::equals			x->separator.equals(x)
String::trim				x->x.trim()
String::concat				(x, y)->x.concat(y)
Integer::valueOf			x->Integer::valueOf(x)
Integer::sum				(x, y)->Integer::sum(x, y)
Integer::new				x->new Integer(x)
Integer[]::new				n->new Integer[n]
只有当lambda表达式的体只调用一个方法而不做其他操作时,才能把lambda表达式重写为方法引用。
// 这里有一个方法调用和一个比较,故不能用方法引用。
s->s.length() == 0
可以在方法引用中使用this,如
this::equals等同于x->this.equals(x)
使用super也是合法的,
- 构造器引用
构造器引用与方法引用类似
Integer::new				x->new Integer(x)
Integer[]::new				n->new Integer[n]
- 变量作用域
lambda表达式有3个部分
a.一个代码块
b.参数
c.自由变量的值,这是指非参数而且不在代码中定义的变量。
表示lambda表达式的数据结构必须存储自由变量的值。
代码块及自由变量有一个术语:闭包。

lambda表达式中捕获的变量必须实际上是事实最终变量。
事实最终变量是指,这个变量初始化之后就不会再为它赋新值。

lambda表达式的体与嵌套块有相同的作用域。
这里同样适用命名冲突和遮蔽的有关规则。
在lambda表达式中声明与一个局部变量同名的参数或局部变量是不合法的。
一个方法中,不能有两个同名的局部变量。lambda表达式中同样也不能有同名的局部变量。
- 处理lambda表达式
1.生成lambda表达式
2.lambda表达式传递到需要一个函数式接口的方法
3.如何编写方法处理lambda表达式
使用lambda表达式的重点是延迟执行。
常用函数式接口
函数式接口			参数类型			返回类型		抽象方法名
Runnable			无				void		run
Supplier			无				T			get
Consumer			T				void		accept
BiConsumer	T,U				void		accept
Function		T				R			apply
BiFunction	T,U				R			apply
UnaryOperator	T				T			apply
BinaryOperator	T,T				T			apply
Predicate		T				boolean		test
BiPredicate	T,U				boolean		test


public static void repeat(int n, Runnable action)
{
	// 若参数2为lambda表达式,调action.run()会执行lambda表达式的主体。
	for(int i = 0; i < n; i++) action.run();
}

repeat(10, ()->System.out.println("Hello"));


public interface IntConsumer
{
	void accept(int value);
}

public static vodi repeat(int n, IntConsumer action)
{
	for(int i = 0; i < n; i++) action.accept(i);
}

repeat(10, i->System.out.println("Countdown: " + (9 - i)));



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/297378.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号