3.2JAVA8新特性

发布时间:2024年01月24日

一、主要新特性

1 Lambda表达式-Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中

2 方法引用- 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

3 stream API-新添加的Stream API(java.util.stream)

4 接口中的静态方法和默认方法-默认方法就是一个在接口里面有了一个实现的方法。

5 optional 类-用来解决空指针异常。

6 Date Time API-加强对日期与时间的处理。

7 函数式接口

二、详情介绍

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

default:

在接口中可定义一个使用default修饰有方法体的方法,接口中可以对这个方法提供默认的一种实现。

1、使用default修饰接口中的方法并且必须有主体;

2、接口的default方法不能够被接口本身调用,需要接口的实例(实现类对象)来调用;

3、接口的default方法可以被子接口继承、覆写或者直接调用;

4、接口的default方法可以被实现类覆写及直接调用;

static:

1、使用static修饰接口中的方法并且必须有主体;

2、接口的static方法只能够被接口本身调用;接口名.方法名(...);

3、接口的static方法不能够被子接口继承;

4、接口的static方法不能够被实现类覆写及直接调用;

2.2函数式接口

2.2.1什么是函数式接口

函数式接口就是有且仅有一个抽象方法的接口,但是可以有多个非抽象方法,函数式接口可以隐式的被转换为Lambda表达式

2.2.2函数式接口的API

1.8之前

java.lang.Runnable

java.util.concurrent.Callable

java.security.PrivilegedAction

java.util.Comparator

java.io.FileFilter

java.nio.file.PathMatcher

java.lang.reflect.InvocationHandler

java.beans.PropertyChangeListener

java.awt.event.ActionListener

javax.swing.event.ChangeListener

1.8新增了

java.util.function 此包中包含了很多类,用来支持 Java的 函数式编程

2.2.3函数式接口的注解

我们在接口前加上

@FunctionalInterface就可以判断该接口是不是函数式接口了

2.3Lambda表达式

2.3.1什么是Lambda表达式

就是对匿名内部类的简写,只有在接口是函数式接口时,才能用Lambda表达式。

2.3.2Lambda表达式的基本写法

先创建一个函数式接口

@FunctionalInterface
public interface ITest {
    void test();
    
}

可以先用匿名内部类的方式表达一下

public class Test {
    public static void main(String[] args) {
        ITest iTest = new ITest() {
            
            public void test() {
                System.out.println("匿名内部类");
            }
        };

现在再来看Lambda表达式的方法

ITest iTest1 = () -> System.out.println("我是Lambda表达式");

就这一句代码就可以将上面的匿名内部类概括了,这是无参无返回值的写法,接下来让我们来看看有参的情况下Lambda表达式该怎么写

两个参数有返回值的简写**

/*1.方法体只有一句可以省略{}
* 2.如果有返回值  可以省略return
* 3.参数列表类型可以省略掉
* 4.如果参数只有一个左边()小括号可以省略
* /
MyInterface mf = (num1,num2)->num1+num2;
System.out.println(mf.sum(10, 12));

一个参数没有返回值的简写**

接口

public interface MyInterface{
	void print(String str);
}

?测试

/*Lambda常规写法*/
MyInterface mi = (String str)->{
	System.out.println(str);
};
/*Lambda简写*/
MyInterface mi2 = str->System.out.println(str);
mi2.print("Hello Lambda");

注意:如果基本类型的变量被Lambda使用了就会变为final 修饰的,所以我们重新赋值时就会报错

3方法的引用?

3.1构造方法的引用

创建一个User类

public class User {
    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public User(String name) {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

再创建一个UserFactroy工厂接口

@FunctionalInterface
public interface UserFactroy {
    User creat(String name,Integer age);
}
/**
 * 构造方法的引用
 */
        UserFactroy userFactroy1 = User::new;//方法引入语法
        UserFactroy userFactroy2 = (name,age) -> new User(name,age);
        System.out.println(userFactroy1.creat("za", 12));
        //被构造的方法与函数接口的抽象方法入参一致
        System.out.println(userFactroy2.creat("zw", 24));

3.2静态方法的引用

 /**
         * 静态方法的引用
         * 语法 : 类名::静态方法名
         *  注意事项:
         *  1被引用的静态方法参数列表和函数式接口中抽象方法的参数一致!!
         *  2接口的抽象方法没有返回值,引用的静态方法可以有返回值也可以没有
         *  3接口的抽象方法有返回值,引用的静态方法必须有相同类型的返回值!!
         *          *    12/13
         */
//输入一个字符串类型将它转化为integer类型的值
        IParse parse = Num::anInt;

//找到类里面的方法,该方法里面的返回值类型应该与接口中的返回值类型一样
        System.out.println(parse.parse("222"));

3.3实例方法的引用

/**
         * 方法的引用
         *  语法 : 对象名::非静态方法名
         *   注意事项:
         *    1被引用的实例方法参数列表和函数式接口中抽象方法的参数一致!!
         *    2接口的抽象方法没有返回值,引用的实例方法可以有返回值也可以没有
         *    3接口的抽象方法有返回值,引用的实例方法必须有相同类型的返回值!!
         *    12/13
         */
//

        String s = "123";
        Function<String, Boolean> function = s::endsWith;
        function.apply("123");

4stream流

4.1什么是stream流

Stream(流)是一个来自数据源的元素队列并支持聚合操作

4.2生成流

stream() ? 为集合创建串行流。

parallelStream() ? 为集合创建并行流。

4.3常用方法

forEach- 来迭代流中的每个数据

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8); 
list.stream().forEach(System.out::println);

map- 方法用于对每个元素修改

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); 
// 获取对应的平方数 
numbers.stream().map( i -> i*i).forEach(System.out::println);

filter-过滤出想要的元素

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); 
//过滤取出每一个不为空的元素
strings.stream().filter(string -> !string.isEmpty()).forEach(System.out::println);

limit-获取指定数量的数据

Random random = new Random();
//从随机流中获取十个随机数:并输出结果
random.ints().limit(10).forEach(System.out::println);

sorted-排序

Random random = new Random(); 
//获取十个随机数,并排序
random.ints().limit(10).sorted().forEach(System.out::println);

collectors-实现了很多归约操作,例如将流转换成集合和聚合元素

5Optional类

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional 类的引入很好的解决空指针异常

善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅。

5.1声明

Optional.of(T t):创建要给Optional实例

Optional.empty():创建一个空的Optional实例

Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空的实例

isPresent():判断是否包含值

orElse(T t):如果调用对象包含值,返回该值,否则返回t

orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值

map(function f):如果有值对其处理,并发挥处理后的Optional ,否则返回Optional.empty()

flatMap(Function mapper):与map类似,要求返回值必须是Optional

6时间日期API-知道有就好啦

三、总结

Jdk1.8的新特性 lambda表达式 方法引用 函数式接口 stream

多线程 线程的创建方式 生命周期 锁机制 synconized与lock区别 threadlocal原理

线程池 线程池原理 常见4种线程池

线程池中最大线程数的设置

文章来源:https://blog.csdn.net/l20120/article/details/135829034
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。