- optional类的理解与使用:
1)public static <T> Optional<T> of(T value): 返回value(非空)的实例
public static<T> Optional<T> empty():返回空实例
public static <T> Optional<T> ofNullable(T value):根据传入值 返回value或空的 实例
Optional()与Optional(T)为私有构造方法@Test public void Test1(){//不推荐采用这种方式 Optional<String> optionalS = Optional.of("Hello"); if(optionalS.isPresent()) System.out.println(optionalS.get()); } @Test public void Test2(){//推荐 Optional<String> optionalS = Optional.of("Hello"); Optional<String> op = Optional.empty(); optionalS.ifPresent(item -> System.out.println(item)); System.out.println(op.orElse("word"));//op为空则打印传入的参数,不为空则打印op本身 }
2)应用:List集合,返回集合或一个为空的集合
@Test public void Test3(){ Employee employee1 =new Employee(); employee1.setName("Liu"); Employee employee2 =new Employee(); employee2.setName("Ze"); Company company = new Company(); company.setName("Hua Zhong"); List<Employee> employeeList = Arrays.asList(employee1,employee2); //构造Employee集合 company.setList(employeeList);//在company中添加集合 List<Employee> employees = company.getList(); Optional<Company> optional = Optional.ofNullable(company); System.out.println(optional.map(mycom->mycom.getList()).orElse(Collections.emptyList())); //传入的集合若不为空,则打印此集合;传入的集合为空,则打印空集合 //输出:1) [] (注释掉company.setList(employeeList);) // 2) [com.learn.jdk8.Employee@39ed3c8d, com.learn.jdk8.Employee@71dac704] } //构造的company与Employee为一对多的关系 class Employee{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } class Company{ private String name; private List<Employee> employees; public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Employee> getList() { return employees; } public void setList(List<Employee> employees) { this.employees = employees; } }
- 方法引用:method reference:实际上是Lambda表达式的一种语法糖。当Lambda表达式只有一行代码,且Lambda表达式的方法恰好是已经存在的,这可以改写成为方法引用的形式。
方法引用共有四类:
1)类名::静态方法名
2)引用名(对象名)::实例方法名
3)类名::实例方法名
说明:实例方法一定是由对象来调用的,此对象就是原方法中接收的Lambda表达式的第一个参数;如果接收多个参数,则除了第一个参数,后面所有的参数都作为这个实例方法的参数。
4)类名::new 说明:此种放式是构造方法的引用(知识补充:构造方法会返回所在类的实例)public class MethodReferenceTest { @Test public void TestLambda(){ Teacher teacher1 = new Teacher("liu", 12); Teacher teacher2 = new Teacher("ze", 55); Teacher teacher3 = new Teacher("tian", 29); Teacher teacher4 = new Teacher("men", 1); List<Teacher> teacherList = Arrays.asList(teacher1,teacher2,teacher3,teacher4); //使用Lambda表达式形式实现 teacherList.sort((t1,t2)->Teacher.SortByage(t1, t2)); teacherList.forEach(t-> System.out.println(t.getAge())); System.out.println("-----------------------"); teacherList.sort((t1,t2)->Teacher.SortByname(t1, t2)); teacherList.forEach(t-> System.out.println(t.getName())); } @Test public void TestMethodReference(){ // 使用方法引用:第一类: // 类名::静态方法名 Teacher teacher1 = new Teacher("liu", 12); Teacher teacher2 = new Teacher("ze", 55); Teacher teacher3 = new Teacher("tian", 29); Teacher teacher4 = new Teacher("men", 1); List<Teacher> teacherList = Arrays.asList(teacher1,teacher2,teacher3,teacher4); teacherList.sort(Teacher::SortByage); teacherList.forEach(t-> System.out.println(t.getAge())); System.out.println("-----------------------"); teacherList.sort(Teacher::SortByname); teacherList.forEach(t-> System.out.println(t.getName())); } @Test public void TestMethodReference2(){ // 使用方法引用:第二类: // 引用名(对象名)::实例方法名 Teacher teacher1 = new Teacher("liu", 12); Teacher teacher2 = new Teacher("ze", 55); Teacher teacher3 = new Teacher("tian", 29); Teacher teacher4 = new Teacher("men", 1); List<Teacher> teacherList = Arrays.asList(teacher1,teacher2,teacher3,teacher4); TeacherCompare teacherCompare = new TeacherCompare(); teacherList.sort(teacherCompare::SortTeacherAge); teacherList.forEach(t-> System.out.println(t.getAge())); System.out.println("-----------------------"); teacherList.sort(teacherCompare::SortTeacherName); teacherList.forEach(t-> System.out.println(t.getName())); } @Test public void TestMethodReference3(){ // 使用方法引用:第三类: // 类名::实例方法名 // 实例方法一定是由对象来调用的,此对象就是sort方法中接收的Lambda表达式的第一个参数 // 如果接收多个参数,则除了第一个参数,后面所有的参数都作为实例方法的参数 // sort方法中lambda表达式为实现Comparator函数接口的int compare(T o1, T o2); 方法 Teacher teacher1 = new Teacher("liu", 12); Teacher teacher2 = new Teacher("ze", 55); Teacher teacher3 = new Teacher("tian", 29); Teacher teacher4 = new Teacher("men", 1); List<Teacher> teacherList = Arrays.asList(teacher1,teacher2,teacher3,teacher4); teacherList.sort(Teacher::Sortage); teacherList.forEach(t-> System.out.println(t.getAge())); System.out.println("-----------------------"); teacherList.sort(Teacher::Sortname); teacherList.forEach(t-> System.out.println(t.getName())); } @Test public void TestMethodReference4(){ // 使用方法引用:第四类:构造方法引用 // 类名::new System.out.println(getString(()->"liu"));//liutest System.out.println(getString(String::new));//test System.out.println(getString2("ze",String::new));//ze 注(构造方法一定会返回当前类的实例) } public String getString(Supplier<String> supplier){ return supplier.get() + "test"; } public String getString2(String str, Function<String,String> function){ return function.apply(str); } } class Teacher{ private String name; private int age; public Teacher(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //定义这两个静态方法是有意为之的,是为了这个示例设计的。 // 平时使用时这样写没有意义(与当前类完全无关)。 //静态方法(实现比较器)以传入 sort(Comparator<? super E> c)方法作为参数 public static int SortByname(Teacher st1, Teacher st2){ return st1.getName().compareTo(st2.getName()); } public static int SortByage(Teacher st1 , Teacher st2){ return st1.getAge() - st2.getAge(); } //以下两种才有意义 public int Sortname(Teacher st){ return this.getName().compareTo(st.getName()); } public int Sortage(Teacher st){ return this.getAge() - st.getAge(); } } class TeacherCompare{ //实例方法(实现比较器)以传入 sort(Comparator<? super E> c)方法作为参数 public int SortTeacherName(Teacher t1, Teacher t2){ return t1.getName().compareTo(t2.getName()); } public int SortTeacherAge(Teacher t1, Teacher t2){ return t1.getAge()- t2.getAge(); } }
- 在Java中实现类(继承父类)的优先级比接口(实现接口)的优先级高。
- 如果有两个接口都有方法类型和参数相同的默认方法(此方法在接口中已被实现,声明为default;新版本中引入默认方法能在接口中增加新的方法的同时避免对使用原有版本代码的破坏性影响),一个类实现了这两个接口,则使用接口中的这默认方法时编译器会报错,可以重写这个方法,若要指定实现其中一个接口的默认方法,则可以在重写的这个方法体中用 接口名.super.方法名 的形式实现。
public class DefaultMethodTest implements MyTest1 ,MyTest2{ @Override public void MyMethod() { System.out.println("MyMethod"); MyTest1.super.MyMethod();//MyTest1 } public static void main(String[] args) { DefaultMethodTest dTest = new DefaultMethodTest(); dTest.MyMethod(); } } interface MyTest1{ default void MyMethod(){ System.out.println("MyTest1"); } } interface MyTest2{ default void MyMethod(){ System.out.println("MyTest2"); } }