JAVA8 新特性

1、java8(JDK1.8)新特性简介

Java 8 是一次重大的发行版更新,引入了大量新特性和改进,以下是 Java 8 的主要特性:

2、Lamdba表达式

Lambda 允许在代码中直接定义匿名函数,简化了对函数式编程的支持。

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
nums.stream()
    .filter(num -> num % 2 == 0) // 过滤偶数
    .map(num -> num * 2) // 将每个元素乘以 2
    .forEach(System.out::println); // 打印结

3、函数式接口

有且仅有一个抽象方法的接口,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。Lambda就是Java中函数式编程的体现
1. Function (函数型接口)
	//输入参数 + 输出返回值
	Function<String,String> function = s -> s+"函数";
	function.apply("test");
	// 输入参数 1 + 输入参数 2 + 输出返回值
	BiFunction<String, String, String> biFunction= (s1, s2) -> s1 + s2;
	biFunction.apply("test","test1");

2. Predicate (断定型接口)
	//输入参数 + 输出返回值 Boolean类型
    Predicate<Integer> predicate =(n)->{return n>0;};
	boolean flag = predicate.test(2);
3. Consumer (消费型接口) 只有参数没有返回值
	//输入参数
	Consumer<String> consumer = s -> System.out.println(s); 
	consumer.accept("a");
	//输入参数1 + 输入参数2
	BiConsumer<String, String> biConsumer = (s1, s2) -> System.out.println(s1 + s2);
	biConsumer.accept("a","b");
4. Supplier (供给型接口) 没有参数只有返回值
	//返回值
	Supplier<Integer> supplier = ()-> {return 1024;};
	Integer num = supplier.get();

4、方法引用和构造引用

若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用是Lambda表达式的另一种表现形式)
主要有有三种语法格式:

对象 :: 实例方法名
类 :: 静态方法名
类 :: 实例方法名
注意:
1、Lambda体中调用方法的参数列表与返回值,要与函数式接口中抽象方法的函数列表和返回值类型保持一致
2、若Lambda 参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,
可以使ClassName :: method

对象::实例方法
 //1.1 接口 变量名 = 匿名内部类
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("consumer1");

        //1.2 接口 变量名 = lambda表达式
        consumer = s -> {
            System.out.println(s);
        };
        consumer.accept("consumer2");

        //1.3 接口 变量名 = 方法引用
        consumer = System.out::println;
        consumer.accept("consumer3");::静态方法
	 //匿名内部类写法
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };
        System.out.println("comparator.compare(10,20) = " + comparator.compare(10, 20));

        //用lambda表达式简化
        comparator = (o1, o2) -> {
            return Integer.compare(o1, o2);
        };
        System.out.println("comparator.compare(10,20) = " + comparator.compare(10, 20));

        //用方法引用简化
        comparator = Integer::compare;
        System.out.println("comparator.compare(10,20) = " + comparator.compare(10, 20));::实例方法
	    Person person = new Person("张三");

        //匿名内部类写法
        Function<Person, String> function = new Function<Person, String>() {
            @Override
            public String apply(Person person) {
                return person.getName();
            }
        };
        System.out.println(function.apply(person));

        //用lambda表达式简化
        function = p -> p.getName();
        System.out.println(function.apply(person));

        //用方法引用简化
        function = Person::getName;
        System.out.println(function.apply(person));::new
		Supplier<String> supplier = new Supplier<String>() {
          @Override
          public String get() {
              return new String("abc");
          }
        };
        System.out.println(supplier.get());

        //用lambda表达式简化
        supplier = () -> new String("abc");
        System.out.println(supplier.get());

        //用方法引用简化
        supplier = String::new;
        System.out.println(supplier.get());

5、Stream API

通过 Stream API 可以轻松处理集合和数组等数据结构,提高了代码的可读性和可维护性。
流(stream) 到底是什么呢?
---- 是数据渠道,用于操作数据源(集合、数组等) 所生成的元素序列

三步骤
1、创建Stream : 一个数据源(如集合、数组) 获取一个流
2、中间操作: 一个中间操作链,对数据源的数据进行处理
3、终止操作: 一个终止操作,执行中间操作链,并产生结果

5.1、创建Stream

// 1、可以通过Collection 系列接口提供的stream() 或parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

// 2、通过Arrays 中的静态方法stream() 获取数组流
Employee emp = new Employee[10];
Stream<Employee> stream = Arrays.stream(emp)

//  3、通过Stream类中的静态方法of()
Stream<String> stream = Stream.of("aa","bb","cc");

// 4、 创建无限流
// 迭代
Stream<String> stream = Stream.iterate(0,(x) -> x + 2);
stream.limit(4L).forEach(System.out::println)
// 生成
Stream.generate(() -> Math.random()).limit(5L).forEach(System.out::println)

5.2、中间操作

// 筛选与切片
filter(Predicate<? super T> predicate)  ----> 接收Lambda,从流中排除某些元素
limit(long maxSize)  ----> 截断流,使其元素不超过给定数量
skip(long n)  ----> 跳过元素,返回一个扔掉前 n 个元素的流,若流中元素不足 n 个,则返回一个空流,与limit(n) 互补
distinct()  ----> 筛选,通过流中所生成的hashcode()equals() 去重,需要重写这两个方法
// 示例
list.stream().filter((e) -> e.getAge > 10).limit(2L).forEach(System.out::println)

// 映射
map(Function<? super T,? extends R> mapper) ----> 接收Lambda,将元素转换成其他形式提取信息,
						接收一个函数作为参数,该函数会被应用到每个元素上,并将映射成一个新的元素
flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
				---->	接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连成一个流

//排序
sorted()  -----> 自然排序
sorted(Comparator<? super T> comparator)  ----> 定制排序

5.3、终止操作


// 查找与匹配
boolean allMatch(Predicate<? super T> predicate)  ----> 检查是匹配所有元素
boolean anyMatch(Predicate<? super T> predicate)  ----> 检查是否至少匹配一个元素
boolean noneMathch(Predicate<? super T> predicate)  ----> 检查是否没有匹配所有元素
Optional<T> findFirst()  ----> 返回描述此流的第一个元素的Optional如果流为空,则返回一个空的Optional
Optional<T> findAny()  ----> 返回流中的任意元素的Optional如果流为空,则返回一个空的Optional
long count() ----> 返回流中的元素的总个数
Optional<T> max(Comparator<? super T> comparator)   ----> 根据提供的 Comparator返回此流的最大元素。
Optional<T> min(Comparator<? super T> comparator)   ----> 根据提供的 Comparator返回此流的最小元素。

// 归约
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)  ----> 可以将流中元素反复结合起来,得到一个值

//收集
<R,A> R collect(Collector<? super T,A,R> collector)  ----> 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到ListSetMap),但是Collectors 实用类提供了很多静态方法,可以方便的创建常见收集器实例
// 示例
List<String> ll = list.stream().collect(Collectors.toList());

并行流与顺序流

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流
Java8 中将并行进行了优化,我们可以很容易的对数据进行并行操作,Stream API 可以声明性的通过parallel() 与 sequential() 在并行流与顺序流之间进行切换

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流
Java8 中将并行进行了优化,我们可以很容易的对数据进行并行操作,Stream API 可以声明性的通过parallel() 与 sequential() 在并行流与顺序流之间进行切换



以下是Stream API中常用的方法:


 1. **filter**(Predicate predicate):过滤出所有符合条件的元素。
```java
   OPtional<String> list = list.stream().filter(d->"1".equals(d.getCode()));
  1. map(Function function):将元素转换为另一种类型。
List<String> list = list.stream().map(T::getValue).collect(Collectors.toSet());
  1. flatMap(Function function):将嵌套的多个流扁平化成一个流。
  2. distinct():去除重复元素。
  3. sorted():排序。
  4. boxed:将基本数据类型转换为对应的包装类类型。
  5. peek(Consumer action):对每个元素执行指定的操作。
  6. limit(long maxSize):限制元素数量。
  7. skip(long n):跳过前 n 个元素。
  8. forEach(Consumer action):对每个元素执行指定的操作。
  9. count():计数。
  10. reduce(BinaryOperator accumulator):将所有元素归约成一个结果。
  11. collect(Collector collector):收集结果到一个集合中。
  12. allMatch(Predicate predicate):判断是否所有元素都符合给定条件。
  13. anyMatch(Predicate predicate):判断是否任何一个元素符合给定条件。
  14. noneMatch(Predicate predicate):判断是否没有任何元素符合给定条件。
  15. findFirst():返回第一个元素。
  16. findAny():返回任意一个元素。

6、接口中的默认方法和静态方法

在Java 8之前,接口只能定义抽象方法,所有的方法都必须由实现该接口的类来实现。但是,在Java 8中,接口可以定义默认方法和静态方法。
默认方法的语法如下:

public interface MyInterface {
    default void myMethod() {
        // 默认方法的实现代码
    }
}

在上面的例子中,myMethod()方法是一个默认方法,它的实现代码是在接口中定义的。注意到默认方法使用了default关键字来修饰。

静态方法的语法如下:

public interface MyInterface {
    static void myStaticMethod() {
        // 静态方法的实现代码
    }
}

7、新时间日期API

在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

Local(本地) − 简化了日期时间的处理,没有时区的问题。

Zoned(时区) − 通过制定的时区处理日期时间。

 LocalDateTime currentTime = LocalDateTime.now();// 获取当前的日期时间
 DateTimeFormatter dt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 LocalDateTime.of(LocalDate.now(),LocalTime.MIN).format(dt); //2021-08-04 00:00:00
 
 LocalDate date1 = currentTime.toLocalDate();  // LocalDate.now() 获取年月日
 
 Month month = currentTime.getMonth(); // 月 
 int day = currentTime.getDayOfMonth(); // 天
 int seconds = currentTime.getSecond(); // 秒

Date与LocalDateTime、LocalDate、LocalTime互相转换

// Date 转成 LocalDateTime、LocalDate、LocalTime
Date date = new Date();
// 系统默认时区 服务器时区不对会导致转换后的时间不对 
ZoneId zoneId = ZoneId.systemDefault(); 
Instant instant = date.toInstant();

LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();

// LocalDateTime 转成 Date
LocalDateTime localDateTime = LocalDateTime.now();
ZoneId zoneId = ZoneId.systemDefault();
Instant instant = localDateTime.atZone(zoneId).toInstant();
Date date = Date.from(instant);

// LocalDate 转成 Date
LocalDate localDate = LocalDate.now();
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
Date date = Date.from(instant);

// LocalTime 转成 Date
LocalTime localTime = LocalTime.now();
LocalDate localDate = LocalDate.now();
ZoneId zone = ZoneId.systemDefault();
Instant instant = LocalDateTime.of(localDate, localTime).atZone(zone).toInstant();
Date date = Date.from(instant);

8、OPtional

Optional类
Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用null 表示一个值不存在,现在 Optional 可以更好的表达这个概念,并且可以避免空指针异常

static <T> Optional<T> Optional.of(T t) ----> 创建一个Optional实例
static <T> Optional<T> Optional.empty() ----> 创建一个空的Optional实例
static <T> Optional<T> Optional.ofNullable(T t) ----> 若t 不为null,创建Optional 实例,否则空实例
boolean isPresent() ----> 判断是否包含值
T orElseGet(Supplier<? extends T> s)  ----> 如果调用对象包含值,返回该值,否则返回 s 获取的值
T osElse(T t) ----> 若果调用对象包含值,返回值,否则返回t

总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值