JDK8的新特性

目录


接口的默认方法和静态方法 

JDK8允许在接口中定义默认方法和静态方法(带有方法体) 

public interface interfaceChange {
    //普通方法---public abstract
    void normalMethod();

    //默认方法---default
    default void defaultMethod(){
        System.out.println("我是jdk1.8中接口中的默认方法,带有方法体的!");
    }

    //静态方法---static
    static void staticMethod(){
        System.out.println("我是jdk1.8中接口中的静态方法,带有方法体的!");
    }
}
public class InterfaceChangeImpl implements interfaceChange{
    //必须重写普通方法
    @Override
    public void normalMethod() {
        System.out.println("我是重写接口的add方法!");
    }

    public static void main(String[] args) {
        InterfaceChangeImpl i = new InterfaceChangeImpl();
        //调用重写方法
        i.normalMethod();
        //调用默认方法
        i.defaultMethod();
        //调用静态方法
        interfaceChange.staticMethod();
    }
}

Lambda表达式

1、匿名内部类

当我们想使用接口中的方法,但是不想创建子类去重写再调用,我们就可以使用匿名内部类来实现快速简洁调用接口中的方法

//如果接口中只有一个方法
public static void main(String[] args) {
        new interfaceChange() {
            @Override
            public void normalMethod() {
                System.out.println("通过匿名内部类实现的方法1!");
            }
        }.normalMethod();
}
//如果接口中有多个方法
public static void main(String[] args) {
        interfaceChange i = new interfaceChange() {
            @Override
            public void normalMethod() {
                System.out.println("通过匿名内部类实现的方法1!");
            }

            @Override
            public void normalMethod2() {
                System.out.println("通过匿名内部类实现的方法2!");
            }
        };
        i.normalMethod();
        i.normalMethod2();
    }

 2、函数式接口(@FunctionalInterface)

2.1 无参函数式接口匿名内部类方式-->Lambda表达式方式 

//无参
@FunctionalInterface//声明为函数式接口---只能有一个普通方法
public interface UserMapper {
    //普通方法
    void get();
}
//无参匿名内部类方式
new UserMapper() {
    @Override
    public void get() {
        System.out.println("无参匿名内部类方式");
    }
}.get();
//无参Lambda表达式方式     ------方法体如果只有一条语句,可省略{ }
UserMapper u = () -> System.out.println("无参Lambda表达式方式");
u.get();
//更精简表达式
((UserMapper)()-> System.out.println("无参Lambda表达式方式")).get();

2.2 有参函数式接口匿名内部类方式-->Lambda表达式方式  

//有参
@FunctionalInterface
public interface StudentMapper {
    public void select(String name,Integer age);
}
//有参匿名内部类方式
System.out.println(
       new StudentMapper() {
              @Override
             public String select(String name, Integer age) {
                        return name + "" + age;
             }
        }.select("Mike",20)
);

//有参Lambda表达式方式
StudentMapper s = (x,y)-> x + "" + y;    ----只有一条语句且有返回值,可省略return和{ }
System.out.println(s.select("Mike", 3));
//更精简表达式
System.out.println( ((StudentMapper) (x, y) -> x + "" + y).select("Mike", 40));

  3、Lambda实战

   3.1 循环遍历

List<Integer> list = Arrays.asList(20,54,10,
//实战---循环遍历
//Lambda方式
list.forEach(s-> System.out.println(s));
//stream流方式
list.stream().forEach(System.out::println);

    3.2 集合排序

//实战---排序
//lambda方式
list.sort((x,y)->x-y);//正序
System.out.println("list = " + list);
list.sort((x,y)->y-x);//逆序
System.out.println("list = " + list);
//stream流方式
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());//正序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());//逆序

     3.3 创建线程

//实战---线程
new Thread(()->{ System.out.println("线程开始!"); }).start();

方法引用

静态方法引用

        类名::静态方法名

对象方法引用

        类名::实例方法名

实例方法引用

        对象实例::方法名

构造函数引用

        类名::new

Optional 

创建Optional容器:

public static void main(String[] args) {
    //创建一个空的Optional容器
    Optional<Object> empty = Optional.empty();
    //创建一个非空的Optional容器(参数必须有值)
    Student s = new Student("MIke",20,"大学");
    Optional<Student> op = Optional.of(s);
    //创建一个可接受null参数的Optional(主用)
    Optional<Student> s1 = Optional.ofNullable(s);
}

 判断容器中是否为空:

//判断容器中是否为空
boolean present = op.isPresent(); 空->true,非空->false

//判断容器中是否为空,并且可通过Lambda表达式进行下一步操作
op1.ifPresent(p->p.setName("李四"));
Optional.ofNullable(s).ifPresent(p->p.setAge(0)); //(主用)
System.out.println(s);

获取容器中的对象:

//获取容器中的对象
Student s1 = null;
Student s2 = new Student("Amy",55,"硕士");
//get()   如果为空报异常
Student student = Optional.ofNullable(s1).get();
//get()   正常则返回对象
Student student2 = Optional.ofNullable(s2).get();
//orElse()  如果为空则返回其他的对象,像三目运算符(s1==null?s2:s1)
Student student3 = Optional.ofNullable(s1).orElse(new Student("Jghn",44,"博士"));
//orElseThrow()    如果为空则抛出异常
Student student4 = Optional.ofNullable(s1).orElseThrow(()->new RuntimeException("对象为空!!"));

Stream流

 1、遍历、遍历筛选(foreach/filter)

List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
//普通遍历
list.stream().forEach(System.out::println);
//筛选遍历
list.stream().filter(s -> "张三".equals(s)||"李四".equals(s)).forEach(System.out::println);

List<Student> list1 = new ArrayList<>();
list1.add(new Student("Mike",20,"大学"));
list1.add(new Student("Amy",21,"大学"));
list1.add(new Student("Jhon",22,"高中"));
list1.add(new Student("Lihua",10,"初中"));
//普通遍历
list1.stream().forEach(System.out::println);
//筛选遍历并输出新的集合
List<Student> collect = list1.stream().filter(s -> s.getAge() <= 20).collect(Collectors.toList());
System.out.println("年龄小于等于20的学生:collect = " + collect);
//遍历筛选符合条件的元素并且指定属性返回
List<String> collect1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).map(Student::getName).collect(Collectors.toList());
System.out.println("学历为大学的学生:collect1 = " + collect1);

2、聚合函数、排序(max/min/count/sorted)

max/min: 

List<String> list2 = Arrays.asList("1","30","55","78","9999","55");
List<Integer> list3 = Arrays.asList(10,30,55,78,9999);
//取字符串最大长度
Optional<String> max = list2.stream().max(Comparator.comparing(String::length));
System.out.println("max = " + max.get());
//取Integer最大值
Optional<Integer> max1 = list3.stream().max((Integer::compareTo));
System.out.println("max1 = " + max1.get());
//取对象属性中年龄最大的
Optional<Student> max2 = list1.stream().max(Comparator.comparing(Student::getAge));
System.out.println("max2 = " + max2.get());

---------最小值类推即可

count: 

//计数
long count = list2.stream().filter(s -> "55".equals(s)).count();
System.out.println("属性为“55”的元素有:count = " + count);
long count1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).count();
System.out.println("大学生有:count = " + count1);

sorted: 

//方式一:
//正序
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());

//逆序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());

//方式二:
//正序
list.stream().sorted((x,y)->x-y).forEach(System.out::println);
list1.stream().sorted((x,y)->x.getAge()-y.getAge()).forEach(System.out::println);
//逆序
list.stream().sorted((x,y)->y-x).forEach(System.out::println);
list1.stream().sorted((x,y)->y.getAge()-x.getAge()).forEach(System.out::println);

 3、映射(map)

List<String> list4 = Arrays.asList("abcd", "bcdd", "defde", "fTr");
//String类型集合将小写转大写
list4.stream().map(String::toUpperCase).forEach(System.out::println);
//Integer类型集合每个元素+5
List<Integer> integerList = list3.stream().map(s -> s += 5).collect(Collectors.toList());
System.out.println("每个元素+5之后的新integerList = " + integerList);
//实体集合将每个学生的年龄-5
List<Student> collect = list1.stream().map(s -> {
    Integer age = s.getAge();
    s.setAge(age -= 5);
    return s;
}).collect(Collectors.toList());
System.out.println("年龄全部-5的新集合是:collect = " + collect);

4、规约(reduce)

//Integer集合求和
Optional<Integer> reduce = list3.stream().reduce(Integer::sum);
//Optional<Integer> reduce = list3.stream().reduce((x, y) -> x + y);
System.out.println("和为:reduce = " + reduce.get());
//Integer集合求积
Optional<Integer> reduce1 = list3.stream().reduce((x, y) -> x * y);
System.out.println("积为:reduce1 = " + reduce1.get());
//String集合求组合
Optional<String> reduce2 = list4.stream().reduce((x, y) -> x + y);
System.out.println("组合为:reduce2 = " + reduce2.get());
//实体集合求年龄总和
Optional<Integer> reduce3 = list1.stream().map(Student::getAge).reduce(Integer::sum);
System.out.println("年龄总和为:reduce3 = " + reduce3.get());

5、收集、转换(collect) 

从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。

collect主要依赖java.util.stream.Collectors类内置的静态方法。

收集成List:Collectors.toList()

收集成Set:Collectors.toSet()   (注:对象收集要去重的话需要重写hashCode和toString

收集成Map:Collectors.toMap()   

List<Integer> list5 = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20, 7);

//将偶数收集起来
List<Integer> collect = list5.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println("collect = " + collect);

//将奇数收集起来并且不重复
Set<Integer> collect1 = list5.stream().filter(x -> x % 2 != 0).collect(Collectors.toSet());
System.out.println("collect1 = " + collect1);

//将实体集合中年龄大于等于20的收集起来--List
List<Student> collect2 = list1.stream().filter(s -> s.getAge() >= 20).collect(Collectors.toList());
System.out.println("collect2 = " + collect2);

//将实体集合中年龄小于等于20的收集起来--Map
Map<?, Student> collect3 = list1.stream().filter(s -> s.getAge() < 20).collect(Collectors.toMap(Student::getName, s -> s));
System.out.println("collect3 = " + collect3);

 

新的日期API 

 ​​​​

//1、设计不合理并且是可变的,线程不安全
Date date = new Date(2020,7,26);

//2、时间格式化并且线程不安全
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(simpleDateFormat.format(date));

 

 

Date、Calendar、SimpleDateFormat都是线程不安全的。而JDK8加入了LocalDate、LocalTime、LocalDateTime、DateTimeFormatter通过加了Final修饰实现了不可变,解决线程安全问题。

//新的LocalDate
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2024,7,26);

//新的LocalTime
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = LocalTime.of(16,41,50);

//新的LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2024,7,26,16,41,50);

//新的DateTimeFormatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
System.out.println(dateTimeFormatter.format(localDateTime));
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH-mm-ss");
System.out.println(dateTimeFormatter1.format(localDateTime));

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值