这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
1. interface 中的 static 方法和 default 方法
在 JDK1.8 之前,Java 中针对接口的特性有:接口中可以包含变量和方法。接口中的变量被默认指定为 public static final 类型,常见的就是在接口中定义一些常量值,接口中的方法则默认是 public abstract 类型的抽象方法,这个不需要我们进行显示指定,接口中的成员一律默认是 public 类型。
在 JDK1.8 中针对接口增加两大特性。
1.1 static 方法
在 JDK1.8 中,可以在接口中定义一个或多个静态方法,用法同普通 static 方法类似。
public interface InterfaceA {
/**
* 接口中的静态方法
*/
static void showStaticMethod() {
System.out.println("showStaticMethod");
}
public static void main(String[] args) {
InterfaceA.showStaticMethod();
}
}
注意:接口中的静态方法无法被它的实现类进行继承,即只有当前接口能进行访问。而接口中的静态变量是可以被继承的。
1.2 default 修饰符
类、成员变量或方法没有 private、protected 或 public 修饰符修饰,则默认是 default 类型。在 JDK1.8 中针对接口中方法可以通过 default 修饰符定义,在接口中,增加 default 方法, 是为了既有的 Java 类库的类增加新的功能, 且不必对这些类重新进行设计。 比如, 只需在 Collection 接口中 增加 default Stream stream(), 相应的 Set 和 List 接口以及它们的子类都包含此的方法, 不必为每个子类都重新copy这个方法。
在 Java8 中针对接口内的方法修饰符有:public、default、abstract,default 修饰的方法在接口中进行实现,接口的实现类可以直接调用,如果有需要可以进行重写。
示例:
public interface InterfaceA {
public static String tag="dsw";
/**
* 接口中的静态方法
*/
static void showStaticMethod() {
System.out.println("showStaticMethod");
}
default void showDefaultMethod() {
System.out.println("showDefaultMethod");
}
}
这里我们可以参照 InterfaceA 定义一个实现类。
class InterfaceClass implements InterfaceA {
@Override
public void doAbstract() {
System.out.println("doAbstract");
}
@Override
public void showDefaultMethod() {
InterfaceA.super.showDefaultMethod();
}
}
从上面可以看到,实现类是可以针对接口中的 default 方法进行重写来满足自身的需要。同时如果实现多个接口,且接口中拥有相同的 default 方法和 static 方法,则需要通过 接口名.super.方法名进行指定。
2. Lambda 基本使用
在 Java 近年来的版本更新中,重大的版本更新莫过于 Java 5,在 Java 5 的更新中引入了“泛型”、“注解”、“枚举”和“自动拆装箱”等,本次在 Java 8 中引入 Lambda 的操作堪比 Java 5 的版本更新,Lambda 表达式用于替代函数式接口(比如 Runnbale),用于简化程序的复杂性。
同时在 Java 8 的版本中通过 Lambda 表达式增强集合的操作,引入了 ‘java.util.function’ 和 ‘java.util.stream’ 两个包,极大简化针对集合的操作。
Lambda 表达式基本使用
2.1 基本语法
基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }
Lambda 表达式由参数、-> 和实现主体 三大部分组成。
2.2 常见格式
Lambda 表达式一些常见的格式:
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其3倍的值
x -> 3 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
针对具体的接口示例:
public class CreateSecretKey {
public static void main(String[] args) {
/**
* 无参数 lambda 表达式
*/
Runnable runnable = ()->{
System.out.println("No Parameters");
};
/**
* 一个参数的 lambda 表达式
*/
OneParameter oneParameter = x -> {
System.out.println("One Param:" + x);
};
/**
* 两个参数的 lambda 表达式
*/
TwoParameters twoParameters = (x, y) -> {
System.out.println("Two Param:" + x + ":" + y);
};
/**
* 字符串参数的 lambda 表达式
*/
StringParam strParam = str -> {
System.out.println("String Param:" + str.length());
};
}
}
interface OneParameter {
void oneParam(int one);
}
interface TwoParameters {
void twoParam(int one, int two);
}
interface StringParam {
void strParam(String str);
}
2.3 函数式接口
在 Java8 中引入了函数式接口的概念,函数式接口中只能定义一个抽象方法(除了隐含的Object对象的公共方法),这里不包含 default 和 static 修饰的方法。 因此最开始也就做SAM类型的接口(Single Abstract Method)。函数式接口通过注解 FunctionalInterface 进行标识。
比如在 JDK1.8 中的 Runnabhle 接口。
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
在 Java8 中引入了预置的四种函数接口:
- Function<T,R>:接受一个输入参数,返回一个结果
- Consumer:接受一个输入参数,无返回结果
- Predicate:接受一个输入参数,返回一个布尔类型结果
- Supplier:无参数,返回一个结果
1. Function<T,R> 接口
Function接口 接受一个输入参数T,返回一个结果R。
@FunctionalInterface
public interface Function<T, R> {
/**
* 给定一个值,返回处理结果
*/
R apply(T t);
/**
* 获取 function 接口 apply 方法,以 before 函数的 apply 方法结果作为参数
* @param before
* @return
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 返回一个 执行 after 函数对象 apply 方法的 函数对,after 函数参数是当前函数对象 apply 方法执行结果
* @param after
* @return
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
示例: 定义一个 Function 对象。
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
Function 接口方法演示
public static void main(String[] args) {
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
Function<Integer, Integer> funCompose = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer t) {
return t + 5;
}
};
Function<String, String> funAndThen = new Function<String, String>() {
@Override
public String apply(String t) {
return "The result:" + t;
}
};
String result = fun.apply(1);
System.out.println(result);
String compose = fun.compose(funCompose).apply(5);
System.out.println(compose);
String andThen = fun.andThen(funAndThen).apply(8);
System.out.println(andThen);
}
// 输出结果
This is number:1
This is number:10
The result:This is number:8
在上面的演示示例中,我们可以结合 lambda 表达式进行优化。
public static void main(String[] args) {
Function<Integer, String> fun = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return "This is number:" + t;
}
};
String compose = fun.compose((Integer x)->{
return x+5;
}).apply(5);
System.out.println(compose);
String andThen = fun.andThen((String apply)->{
return "The result:" + apply;
}).apply(8);
System.out.println(andThen);
}
// 输出结果
This is number:1
This is number:10
The result:This is number:8
2. Consumer 接口
代表了 接受一个输入参数并且无返回的操作。
@FunctionalInterface
public interface Consumer<T> {
/**
* 接收参数执行操作,无返回值
* @param t the input argument
*/
void accept(T t);
/**
* 限制性 accept 方法,再执行 after 的 accept 方法。
* @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); };
}
}
示例:
public static void main(String[] args) {
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println("This is accept number:" + t);
}
};
consumer.andThen((Integer x)->{
System.out.println("This is after accept number:" + x);
}).accept(5);;
}
// 执行结果
This is accept number:5
This is after accept number:5
3. Predicate 接口
输入一个参数,返回一个布尔类型结果。
@FunctionalInterface
public interface Predicate<T> {
// 执行判断 test 逻辑
boolean test(T t);
// 当前 Predicate 和 other 的运算结果进行 and 运算
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
// Preidcate 接口进行取反
default Predicate<T> negate() {
return (t) -> !test(t);
}
// 当前 Predicate 和 other 的运算结果进行 or 运算
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
// 判断 是否相等
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
示例:
public static void main(String[] args) {
Predicate<Integer> predicate = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
if (t > 5) {
return false;
} else {
return true;
}
}
};
System.out.println("test:" + predicate.test(5));//以 5 计算,返回 true
System.out.println("negate:" + predicate.negate().test(5)); //进行 test 的取反,为 false
System.out.println("isEqual:" + Predicate.isEqual(6).test(5));//判断是否相等,不相等,false
boolean and = predicate.and((Integer x)->{
if (x >10) {
return false;
} else {
return true;
}
}).test(6);
System.out.println("and:" + and);//and 运算,一真一假为false
boolean or = predicate.or(x ->{
if (x > 10 ) {
return false;
} else {
return true;
}
}).test(6);
System.out.println("or:" + or);//or 运算,一真一假为true
}
//结果
test:true
negate:false
isEqual:false
and:false
or:true
4. Supplier 接口
无参数返回一个结果。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
示例:
public static void main(String[] args) {
Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
return 5;
}
};
System.out.println(supplier.get());
}
//结果