匿名類
- 當(dāng)接口钮糖、抽象類的實(shí)現(xiàn)類梅掠,在整個(gè)項(xiàng)目中只用過(guò)一次,可以考慮使用匿名類
- 定義一個(gè)接口或抽象類
public interface Eatable { String name(); int energy(); }
- 在main方法中店归,直接new一個(gè)這個(gè)接口的匿名類
打印結(jié)果public static void main(String[] args) { // TODO Auto-generated method stub String string = "你是:"; Eatable eatable = new Eatable() { @Override public String name() { // TODO Auto-generated method stub return string + "君無(wú)殤"; } @Override public int energy() { // TODO Auto-generated method stub return 100; } }; System.out.println(eatable.name() + "阎抒,能量值:" + eatable.energy()); }
你是:君無(wú)殤,能量值:100
- 匿名類不能定義除編譯時(shí)常量以外的任何static成員
- 匿名類只能訪問final或者有效final的局部變量
- 匿名類可以直接訪問外部類中的所有成員(即使被聲明為private)
匿名類只有在實(shí)例相關(guān)的代碼塊中使用消痛,才能直接訪問外部類中的實(shí)例成員(實(shí)例變量挠蛉、實(shí)例方法) - 匿名類不能自定義構(gòu)造方法、但可以有初始化塊
匿名類的常見用途
- 代碼傳遞
- 定義一個(gè)Times類肄满,并添加一個(gè)test靜態(tài)方法谴古,再在這個(gè)類中定義一個(gè)抽象類Block
public class Times { abstract class Block{ abstract void execute(); } public static void test(Block block) { long begin = System.currentTimeMillis(); block.execute(); long end = System.currentTimeMillis(); double duration = (end - begin) / 1000.0; System.out.println("耗時(shí):" + duration + "秒"); } }
- 在main方法中調(diào)用test方法,并申明一個(gè)匿名類
打印結(jié)果為:public static void main(String[] args) { // TODO Auto-generated method stub Times.test(new Times().new Block() { int add = 0; @Override void execute() { // TODO Auto-generated method stub int number = 100000000; for (int i = 0; i < number; i++) { add++; } } }); }
耗時(shí):0.007秒
- 過(guò)濾器
例如Arrays.sort的排序稠歉,默認(rèn)是升序排列public static void main(String[] args) { // TODO Auto-generated method stub Integer[] nums = {1, 4, 6, 2, 8, 3, 9, 7, 5}; //數(shù)據(jù)源:[1, 4, 6, 2, 8, 3, 9, 7, 5] System.out.println("數(shù)據(jù)源:" + Arrays.toString(nums)); //升序 Arrays.sort(nums); //升序:[1, 2, 3, 4, 5, 6, 7, 8, 9] System.out.println("升序:" + Arrays.toString(nums)); //降序 Arrays.sort(nums, new Comparator<Integer>() {//匿名類 @Override public int compare(Integer o1, Integer o2) { // TODO Auto-generated method stub return o2 - o1; } }); //降序:[9, 8, 7, 6, 5, 4, 3, 2, 1] System.out.println("降序:" + Arrays.toString(nums)); }
- 回調(diào)
比如進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求時(shí)掰担,請(qǐng)求數(shù)據(jù)的返回等問題。
Lambda(函數(shù)式接口)
- 函數(shù)式接口(Function Interface):只包含1個(gè)抽象方法的接口
可以在接口上面加上@FunctionInterface注解怒炸,便是它是一個(gè)函數(shù)式接口 - 只能訪問final或者有效final的局部變量
- 沒有引入新的作用域
public class Times { @FunctionalInterface public interface Block{ void execute(); } public static void test(Block block) { long begin = System.currentTimeMillis(); block.execute(); long end = System.currentTimeMillis(); double duration = (end - begin) / 1000.0; System.out.println("耗時(shí):" + duration + "秒"); } }
打印結(jié)果public static void main(String[] args) { // TODO Auto-generated method stub Times.test(() -> { int num = 1000000000; for (int i = 0; i < num; i++) { } }); }
耗時(shí):0.001秒
方法引用
如果Lambda中的內(nèi)容僅僅是調(diào)用某個(gè)方法带饱,可以使用方法引用(Method Reference)來(lái)簡(jiǎn)化
-
引用類方法
- 創(chuàng)建函數(shù)接口
@FunctionalInterface public interface Testable { int test(int v1, int v2); }
- 使用Lambda表達(dá)式
Testable t1 = (v1, v2) -> Math.max(v1, v2); System.out.println(t1.test(30, 40));
- 使用方法引用
Testable t2 = Math::max; System.out.println(t2.test(30, 40));
-
引用特定對(duì)象的實(shí)例方法
- 創(chuàng)建函數(shù)接口,對(duì)象和在Main文件中靜態(tài)方法
@FunctionalInterface public interface Testable { void test(int v1); }
public class Person { public void setAge(int age) { System.out.println("Person - setAge -" + age); } }
static void execute(Testable t, int v) { t.test(v); }
- 使用Lambda表達(dá)式
execute(v -> System.out.println(v), 10); execute(v -> new Person().setAge(v), 10);
- 使用方法引用
execute(System.out::println, 10); execute(new Person()::setAge, 10);
-
引用特定類型的任意對(duì)象的實(shí)例方法
- 創(chuàng)建一個(gè)字符串?dāng)?shù)組
String[] strings = { "Jack", "james", "Apple", "abort" };
- 使用Lambda表達(dá)式
Arrays.parallelSort(strings, (s1, s2) -> s1.compareToIgnoreCase(s2));
- 使用方法引用
Arrays.parallelSort(strings, String::compareToIgnoreCase);
-
引用構(gòu)造方法
- 創(chuàng)建函數(shù)接口阅羹,包含有構(gòu)造方法的對(duì)象
@FunctionalInterface public interface Testable { Object test(int v1); }
public class Person { public Person(int age) { System.out.println("Person -" + age); } }
- 使用Lambda表達(dá)式
Testable t1 = v -> new Person(v); System.out.println(t1.test(18));
- 使用方法引用
Testable t1 = Person::new; System.out.println(t1.test(18));
-
引用當(dāng)前類中定義的實(shí)例方法
- 創(chuàng)建函數(shù)接口勺疼,對(duì)象
@FunctionalInterface public interface Testable { void test(int v1); }
public class Person { public void setAge(int age) { System.out.println("Person - setAge -" + age); } }
- 使用Lambda表達(dá)式
public void show() { Testable t1 = v -> setAge(v); t1.test(10); }
- 使用方法引用
Testable t1 = this::setAge; t1.test(10);
-
引用父類中定義的實(shí)例方法
- 創(chuàng)建函數(shù)接口,對(duì)象和這個(gè)對(duì)象的子類
@FunctionalInterface public interface Testable { void test(int v1); }
public class Person { public void setAge(int age) { System.out.println("Person - setAge - " + age); } }
public class Student extends Person { public void setAge(int age) { System.out.println("Student - setAge - " + age); } }
- 使用Lambda表達(dá)式
Testable t1 = v -> super.setAge(v); t1.test(10);
- 使用方法引用
Testable t2 = super::setAge; t2.test(10);