interface Strategy {
String approach(String msg);
}
class Soft implements Strategy {
@Override
public String approach(String msg) {
return msg.toLowerCase() + "?";
}
}
class Unrelated {
static String twice(String msg) {
return msg + " " + msg;
}
}
public class Strategize {
Strategy strategy;
String msg;
Strategize(String msg) {
strategy = new Soft(); // [1]
this.msg = msg;
}
void communicate() {
System.out.println(strategy.approach(msg));
}
void changeStrategy(Strategy strategy) {
this.strategy = strategy;
}
}
public class Main {
public static void main(String[] args) {
Strategy[] strategies = {
new Strategy() { // [2]
@Override
public String approach(String msg) {
return msg.toLowerCase() + "!";
}
},
msg -> msg.substring(0, 5), // [3]
Unrelated::twice // [4]
};
Strategize s= new Strategize("Hello there");
s.communicate();
for (Strategy newStrategy: strategies) {
s.changeStrategy(newStrategy);
s.communicate();
}
}
}
/* Output
hello there?
hello there!
Hello
Hello there Hello there
*/
- [1] Soft 实现了 approach
- [2] 通过生成匿名内部类实现
- [3] 通过 Java 8 的 lambda 表达式实现,和匿名内部类有相同的效果,但是写的代码少很多
- [4] Java 8 的方法引用,:: 左边的是类名,:: 右边的是方法名,不带参数列表
Lambda 表达式
interface Description {
String brief();
}
interface Body {
String detailed(String head);
}
interface Multi {
String twoArg(String head, Double d);
}
public class LambdaExpressions {
static Body bod = h -> h + " No Parens!"; // [1]
static Body bod2 = (h) -> h + "More details"; // [2]
static Description desc = () -> "Short info"; // [3]
static Multi mult = (h, n) -> h + n; // [4]
static Description moreLines = () -> { // [5]
System.out.println("moreLines()");
return "from moreLines()";
};
public static void main(String[] args) {
System.out.println(bod.detailed("Oh!"));
System.out.println(bod2.detailed("Hi!"));
System.out.println(desc.brief());
System.out.println(mult.twoArg("Pi!", 3.14159));
System.out.println(moreLines.brief());
}
}
/*
Oh! No Parens!
Hi!More details
Short info
Pi!3.14159
moreLines()
from moreLines()
*/
- [1] 单个参数,没有括号
- [2] 参数带括号
- [3] 没有参数,必须使用括号
- [4] 多个参数必须是用括号
- [5] 多行代码,要用 {},如果有返回值,要用 return
递归
interface IntCall {
int call(int arg);
}
public class RecursiveFactorial {
static IntCall fact;
public static void main(String[] args) {
fact = n -> n == 0 ? 1 : n * fact.call(n - 1);
for (int i = 0; i <= 10; i++) {
System.out.println(fact.call(i));
}
}
}
/*
1
1
2
6
24
120
720
5040
40320
362880
3628800
*/
方法引用
interface Callable { // [1]
void call(String s);
}
class Describe {
void show(String msg) { // [2]
System.out.println(msg);
}
}
public class MethodReferences {
static void hello(String name) { // [3]
System.out.println("Hello" + name);
}
static class Description {
String about;
Description(String desc) {
about = desc;
}
void help(String msg) { // [4]
System.out.println(about + " " + msg);
}
}
static class Helper {
static void assist(String msg) { // [5]
System.out.println(msg);
}
}
public static void main(String[] args) {
Describe d = new Describe();
Callable c = d::show; // [6]
c.call("call()"); // [7]
c = MethodReferences::hello; // [8]
c.call("Bob");
c = new Description("valuable")::help; // [9]
c.call("information");
c = Helper::assist; // [10]
c.call("Help!");
}
}
/*
call()
HelloBob
valuable information
Help!
*/
- [1] 定义一个接口
- [2] 参数和返回值都符合 Callable 的 call() 方法
- [3] hello() 遵循 Callable 的 call 方法
- [4] help 不是 static 方法
- [5] assist() 是 static 方法
- [6] d::show 赋值给 c
- [7] 通过 c 调用 show 方法
- [8] static 方法引用
- [9] 实例方法引用
- [10] static 方法引用
Runnable
class Go {
static void go() {
System.out.println("Go::go()");
}
}
public class RunnableMethodReference {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Anonumous");
}
}).start();
new Thread(
() -> System.out.println("lambda")
).start();
new Thread(Go::go).start();
}
}
/*
Anonumous
lambda
Go::go()
*/
Unbound Method References
class X {
String f() { return "X::f()"; }
}
interface MakeString {
String make();
}
interface TransfromX {
String transform(X x);
}
public class UnboundMethodReference {
public static void main(String[] args) {
// MakeString ms = X::f; // [1]
TransfromX sp = X::f;
X x = new X();
System.out.println(sp.transform(x)); // [2]
System.out.println(x.f());
}
}
/*
X::f()
X::f()
*/
- [1] 这里看起来方法的签名是一致的,其实不然,X::f 的签名是 X -> String, 因为实例方法还有一个 this 参数
- [2] 和 TransfromX 签名一致
Constructor Method References
函数的组合,可以通过 compose
来进行函数的组合,例如
import java.util.function.*;
public class FunctionComposition {
static Function<String, String>
f1 = s -> {
System.out.println(s);
return s.replace('A', '_');
},
f2 = s -> s.substring(3),
f3 = s -> s.toLowerCase(),
f4 = f1.compose(f2).andThen(f3);
public static void main(String[] args) {
System.out.println(f4.apply("ABCxyzASDASDASDAS"));
}
}
/*
xyzASDASDASDAS
xyz_sd_sd_sd_s
*/
自定义异常
class SimpleExpection extends Exception {}
public class InheritingExceptions {
public void f() throws SimpleExpection {
System.out.println("f");
throw new SimpleExpection();
}
public static void main(String[] args) {
InheritingExceptions exc = new InheritingExceptions();
try {
exc.f();
} catch (SimpleExpection e) {
System.out.println("catch");
}
}
}
/* 输出
f()
Caught
*/
网友评论