Java新特性

1. Lambda表达式

1.1 Lambda说明

1.1.1定义

Lambda表达式基于数学中的λ演算得名,对应java中的lambda抽象,是一个匿名函数,即没有函数名的函数。

1.1.2好处

使用 Lambda 表达式可使代码变的更加简洁紧凑。并且Lambda表达式可和Stream API等相结合,使代码更加简洁紧凑。Lambda 表达式经常用来替代部分匿名内部类。

1.1.3语法

(参数列表) -> {执行语句}
参数:要重写的方法的形参列表
-> :lambda运算符
表达式/语句体:要实现的方法的方法体

1.1.4本质

Lambda 表达式是一种匿名函数(不是匿名内部类),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。它实质属于函数式编程的概念。

1.2. Lambda表达式的使用

1.2.1 无参,无返回值

/*
    无返回值,无参数
 */
public interface B {
    void test();
}
//匿名内部类实现
B b = new B() {
    @Override
    public void test() {
        System.out.println("匿名内部类实现");
    }
};
b.test();//匿名内部类实现

//Lambda表达式实现,匿名函数实现
B b1 = () -> {
    System.out.println("Lambda表达式实现");
};
b1.test();//Lambda表达式实现

无参,无返回值 Lambda表达式的简化:
1.实现的方法体中只有一条执行语句(创建变量不可以),{}可以省略不写
2.实现的方法体中有多条执行语句,不可以省略{}

//简化,实现的方法体中只有一条执行语句(创建变量不可以),{}可以省略不写
B b2 = () -> System.out.println("Lambda表达式实现-简化");
b2.test();//Lambda表达式实现-简化

//实现的方法体中有多条执行语句,不可以省略{}
B b3 = () -> {
    int a = 10;
    System.out.println("Lambda表达式实现");
    int z = 20;
};
b3.test();//Lambda表达式实现

1.2.2无返回值,一个参数

/*
    无返回值,一个参数
 */
public interface C {
    void test(String name);
}
//Lambda表达式实现
C c1 = (String name) -> {
    System.out.println(name);
};
c1.test("zs");

//实现方法的形参名可以和被实现方法的参数名不同
C c2 = (String xx) -> {
    System.out.println(xx);
};
c2.test("ls");

无返回值,一个参数Lambda表达式的简化:
1.实现方法中的参数类型可以省略,运行时自动类型推断
2.实现方法中的参数个数只有一个,可以省略()

//简化:实现方法中的参数类型可以省略,运行时自动类型推断
C c4 = (name) ->  System.out.println(name);
c4.test("c4");
//简化:实现方法中的参数个数只有一个,可以省略()
C c5 = name ->  System.out.println(name);
c5.test("c5");

1.2.3没有返回值,多个参数

/*
    没有返回值,多个参数
 */
public interface D {
    void test(int i, int j);
}
//Lambda表达式实现接口
D d = (int i,int j) -> {
    System.out.println(i + j);
};
d.test(1,2);

1.2.4有返回值,无参数

/*
    有返回值,无参数
 */
public interface E {
    int test();
}
//Lambda表达式实现接口
E e = () -> {return 100;};
System.out.println(e.test());

有返回值,无参数Lambda表达式的简化:
1.只有一条执行语句并且为返回结果,return和{}必须同时省略

//简化1:只有一条执行语句并且为返回结果,return和{}必须同时省略
E e1 = () -> 200;
System.out.println(e1.test());

1.2.5有返回值,一个参数

/*
    有返回值,一个参数
 */
public interface F {
    String test(int a);
}
//lambda表达式实现接口
F f = (int a) -> {return "返回" + a;};
System.out.println(f.test(10));

//简化
F f1 = a -> "返回" + a;
System.out.println(f1.test(20));

1.2.6有返回值,多个参数

/*
    有返回值,多个参数
 */
public interface G {
    int test(int i, int j);
}
G g = (int i, int j) -> {return i + j;};
System.out.println(g.test(1, 2));

//简化
G g1 = (i,j) -> i + j;
System.out.println(g1.test(2, 2));

1.3Lambda表达式的注意事项

Lambda表达式的注意事项:
1.实现的方法体中只有一条执行语句(创建变量不可以),{}可以省略不写;实现的方法体中有多条执行语句,不可以省略{}
2.有参的Lambda表达式实现方法中的参数类型可以省略,运行时自动类型推断;实现方法中的参数个数只有一个,可以省略()
3.有返回值的Lambda表达式中只有一条执行语句并且为返回结果,return和{}必须同时省略;除了有return还有其他代码不能省略return和{}
4.接口中只能有一个抽象方法

2.函数式接口

2.1定义

只有一个抽象方法(default,static, Object中继承的不算)

2.2作用

在Java中主要用在Lambda表达式和方法引用(想使用Lambda表达式,接口必须为函数式接口)。

2.3 内置的函数式接口

JDK 也提供了大量的内置函数式接口,使得 Lambda 表达式的运用更加方便、高效。这些内置的函数式接口已经可以解决我们开发过程中绝大部分的问题,只有一小部分比较特殊得情况需要我们自己去定义函数式接口。在这里特别介绍四个函数式接口。

  1. Consumer:消费型接口(void accept(T t))。有参数,无返回值
  2. Supplier:供给型接口(T get())。只有返回值,没有入参
  3. Function<T, R>:函数型接口(R apply(T t))。一个输入参数,一个输出参数,两种类型不可不同、可以一致
  4. Predicate:断言型接口(boolean test(T t))。输入一个参数,输出一个boolean类型得返回值

2.3.1消费型接口

//使用Lambda表达式
Consumer consumer1 = o -> {System.out.println(o);};
consumer1.accept("bb");

2.3.2 断言型接口

List<Integer > list = new ArrayList<>();
//一次向集合添加多个数据
Collections.addAll(list,34,56,89,65,87);

//符合条件删除
//使用Lambda表达式实现
list.removeIf((i)->{
  if(i > 80) {
  	return true;//删除
	}
  return false;//保留
});
//遍历
list.forEach(i -> System.out.print(i + "\t"));
System.out.println();

3.方法引用

3.1定义

有时候,Lambda体中可能仅调用一个方法,而不做任何其它事,对于这种情况,通过一个方法名字来引用这个已存在的方法会更加清晰。方法引用是一个更加紧凑,易读的 Lambda 表达式,注意方法引用是一个 Lambda 表达式,方法引用操作符是双冒号 “::”。

3.2方法引用的使用

使用了Lambda表达式,满足下述要求,可以使用方法引用
1.方法体中只有一个调用方法的执行语句
2.函数式接口中方法的参数 和 引用方法的参数个数必须相同
3.函数式接口中方法有返回值,引用的方法也必须有返回值
4.函数式接口中方法的参数类型 和 引用方法的参数类型相同,或者为引用方法的参数类型的子类
5.函数式接口中方法的返回值 和 引用方法的返回值类型相同,或者为引用方法的参数类型的父类

//使用lambda表达式实现
Consumer<Integer> consumer1 = (i)->System.out.println(i);
consumer1.accept(56);

//使用方法引用
Consumer<Integer> consumer2 = System.out::println;
consumer2.accept(56);

4.流式编程

4.1介绍

它是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的聚合操作或者大批量数据操作。
Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。
它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。

4.2步骤

1.创建Stream串行流:从数据源(集合、数组、…)获取流对象(Stream)

//方式1:
List<Integer> list = new ArrayList<>();
Collections.addAll(list,4,6,3,2,1,5);
Stream<Integer> stream = list.stream();

//方式2:
Stream<Integer> stream1 = Stream.of(5,6,2,3,4,8);

//方式3:
int[] ints = {1,5,8,4,7,5,6};
IntStream stream2 = Arrays.stream(ints);

2.中间操作:过滤、排序、…

 Stream<Integer> stream = list.stream()//获取流对象
            .filter(t -> {
                if(t <= 1){
                    return false;//过滤掉
                }
                return true;//保留
            })//过滤
            .map(t -> t+10)
            .distinct()//去除重复
            .sorted()//排序
            .skip(2)//跳过指定次数
            .limit(2);//限制返回1个

3.终止操作:获取最终结果

stream.forEach(System.out::println);//遍历
Set<Integer> collect = stream.collect(Collectors.toSet());//变为指定的集合
Comparator<Integer> comparator = new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return Integer.compare(o1,o2);
    }
};
Comparator<Integer> comparator1 = (o1,o2) -> {
    return Integer.compare(o1,o2);
};
Comparator<Integer> comparator2 = Integer::compare;
//获取最小值
Optional<Integer> min = stream.min(comparator2);
System.out.println(min.get());
//获取最大值
Optional<Integer> max = stream.max(comparator2);
System.out.println(max.get());
//获取剩余元素数量
long count = stream.count();
System.out.println(count);

4.3创建Stream并行流

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

public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建累加器
        long sum = 0;
        //时间刻度值 长整数
        long l = System.currentTimeMillis();
        for (int i = 1; i <= 1000000000L; i++) {
            //sum = sum + i;
            sum += i;
        }
        long l1 = System.currentTimeMillis();
        System.out.println("普通方法所用时间:" + (l1 - l));

        System.out.println(sum);
        System.out.println("--------------------------------");
        
        long l2 = System.currentTimeMillis();
        //创建ForkJoinPool,根据拆分的任务数量创建线程对象
        ForkJoinPool pool = new ForkJoinPool();
        MyTask myTask = new MyTask(1, 1000000000L);
        ForkJoinTask<Long> submit = pool.submit(myTask);
        long l3 = System.currentTimeMillis();
        Long aLong = submit.get();
        System.out.println("多线程所用时间:" + (l3 - l2));
        System.out.println(aLong);
    }
public static class MyTask extends RecursiveTask<Long> {
        long start;
        long end;
        long step = 200;//步长(任务拆分的判断条件)

        public MyTask(long start, long end) {
            this.start = start;
            this.end = end;
        }

        //递归调用的方法(作用:任务的拆分)
        @Override
        protected Long compute() {
            long sum = 0;
            //不再继续拆分,直接计算
            if(end - start < step){
                for (long i = start; i <= end; i++){
                    sum += i;
                }
            }else {
                //拆分任务
                long mid = (start + end) / 2;
                MyTask myTask1 = new MyTask(start, mid);
                MyTask myTask2 = new MyTask(mid + 1, end);
                myTask1.fork();
                myTask2.fork();

                Long join1 = myTask1.join();
                Long join2 = myTask2.join();

                sum = join1 + join2;
            }
            return sum;
        }
    }

5.Optional使用

public static void main(String[] args) {
        AserviceImpl aservice = null;
        aservice = new AserviceImpl();
        /*if(aservice != null){
            aservice.test1();//自定义类实现接口
        }*/

        //获取Optional对象
        //对象为null,空指针异常,对象不为空,value属性存储对象
        //Optional<AserviceImpl> optional = Optional.of(aservice);

        //对象为null,创建了Optional对象,对象不为空,value属性存储对象
        Optional<AserviceImpl> optional1 = Optional.ofNullable(aservice);

        //t为存储在Optional中的对象
        //如果t为null,不会执行ifPresent,t不为null,执行ifPresent
        optional1.ifPresent(t -> {t.test1();});//自定义类实现接口
        //System.out.println(optional1.get());//AserviceImpl{age=10}

        //t:存储在Optional中的对象
        //符合条件的可以进行相关操作
        optional1.filter(t -> {
            if(t.age >= 10){
                //t.age = 100;
                return true;
            }
            //t.age = 200;
            return false;
        });
        //System.out.println(optional1.get());//AserviceImpl{age=100}

        optional1.map(t -> {//大于10
            if(t.age > 10){
                System.out.println("大于10");
                return ">10";
            }
            System.out.println("小于10");
            return "<10";
        });
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值