Java源码系列(8):Java8的新特性

 

目录

Lambda表达式:参数列表,->,具体操作

原理

简单例子

具体使用

遍历list

数组排序(匿名内部类)

数组排序(lamdba表达式)

方法引用:对Lamdba表达式的近一步简化

原理

四种形式

使用

默认方法:接口interface添加默认default方法

原理

为什么要有默认方法

关于默认方法的调用冲突

Stream API

原理

使用


Lambda表达式:参数列表,->,具体操作

原理

Lamdba表达式的本质是一个“语法糖”,由编译器推断并将我们转换包装为常规的代码,因此可以使用更少的代码来实现同样的功能。

但是还是不要随便使用,因为如果使用了Lambda表达式,就意味着代码更加简洁,难懂,不容易调试,加大了后期维护的功能。

 

简单例子

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * 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)

具体使用

遍历list

对平常的list进行输出打印,我们平常使用的是for循环遍历,但是在Java8中我们可以使用lamdba表达式,代码量更加少,将原来的三行代码合为了一行代码。

public class Java8 {
  public static void main(String args[]) {
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");

    // 以前的循环方式
    for (String str : list) {
      System.out.print(str + "; ");
    }
    System.out.println();

    // 使用 lambda 表达式
    list.forEach((str) -> System.out.print(str + "; "));
  }
}

数组排序(匿名内部类)

我们对某个数组进行排序的时候,可能比较傻一点的方法,就是手动排序,什么选择排序,直接排序,冒泡排序,归并排序的,但这种比较浪费时间,而且对算法也有一定的要求。稍微好一点的方法就是使用Arrays提供的sort方法,自己写一个comparator,作为匿名内部类,代码如下:

public class Java8 {
  public static void main(String args[]) {
    String[] strs = {"chenchen","huangzengzeng","blibili"};

    //1.使用匿名内部类
    Arrays.sort(strs, new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
        return o1.compareTo(o2);
      }
    });

    List<String> list=Arrays.asList(strs);
    list.forEach(name->System.out.println(name));

  }
}

数组排序(lamdba表达式)

但是有时候觉得上面的代码太冗余了,行数太多,也可以用lamdba表达式,代码如下:

public class Java8 {
  public static void main(String args[]) {
    String[] strs = {"chenchen","huangzengzeng","blibili"};
    
    Arrays.sort(strs,(String o1,String o2)->o1.compareTo(o2));
    List<String> list=Arrays.asList(strs);
    list.forEach(name->System.out.println(name));

  }
}

 

方法引用:对Lamdba表达式的近一步简化

原理

也就是对lambda表达式的近一步简化,减少重复代码。

四种形式

方法引用的四种形式:

  • 引用静态方法->类名称::static 方法名称
  • 引用某个对象的实例的普通方法->实例对象::普通方法
  • 引用某个类的普通方法->特定类::普通方法
  • 引用构造方法->类名称::new

使用

先写一个person对象,用于底下的测试:

public class Person {

  String name;
  int age;

  public Person() {
  }

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }

  public static int compareByAge(Person a, Person b){
    return a.getAge()-b.getAge();
  }

}

 

public class Java8 {
  public static void main(String args[]) {
    Person person1 = new Person("cc", 24);
    Person person2 = new Person("hzz", 23);

    Person[] persons = {person1, person2};

    //1.引用静态方法
    Arrays.sort(persons, Person::compareByAge);

    //2.引用对象的普通方法
    Supplier<String> name =person1::getName;

    //4.引用构造方法
    Supplier<Person> supplier = Person::new;
    Person person=supplier.get();

  }
}

 

默认方法:接口interface添加默认default方法

原理

在接口中添加一个以实现好的方法,且该接口的实现类中不需要实现该方法。

interface GreetingService  
    {
        void sayMessage(String message);
        
        //可以在接口中定义默认方法
        default void sayHello(){
            System.out.println("Hello");
        }
    }

为什么要有默认方法

主要是为了方便扩展已有的接口。如果没有默认方法,实现该接口的所有类都要添加该方法,也就是所有的类都得修改,影响会很大。

如果使用默认方法,可以给已有的接口添加新的方法,而不用修改该接口的所有实现类。

例子来了:在Java8的Iterable接口中添加了一个默认的方法forEach,也正是因为forEach是默认方法,才不用修改Iterable的所有实现类。

 default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

关于默认方法的调用冲突

关于下面的代码,有几个问题?

1.为什么会报错?

2.如果在InterfaceC重写foo方法,还报错吗?

3.如果在InterfaceB去除foo方法,还报错吗?

Stream API

原理

对数据的筛选和统计。

使用


public class Java8 {
  public static void main(String[] args) {
    List<Person> personList = new ArrayList<>();
    personList.add(new Person("cc", 12));
    personList.add(new Person("ls", 23));
    Stream<Person> stream = personList.stream();
    List<Person> newList = stream.filter(p -> p.getAge() > 20).collect(Collectors.toList());

    newList.forEach(person -> System.out.println(person.getName()));
  }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值