jdk8的新特征

1: jdk8中新增的方法

   在jdk8中对接口进行了增强,在jdk8之前

   interface 接口名{

   静态常量:

   抽象方法:

   }

    在jdk8之后

  interface 接口名{

  静态常量:

  抽象方法:

  默认方法:

  静态方法:

  }

  2:默认方法

   在jdk8以前只能有抽象方法和静态常量,会存在一下问题

   如果有接口进行扩展,这个接口的对应的实现类都需要重写,不利于扩展

 2.1:默认方法格式

interface 接口名:{

 修饰符 default 返回值类型  方法名:{

   方法体:

  }

}

package com.example.java8.inter;

public class Demo1Interface {
public static void main(String[] args) {
A b = new B();
System.out.println(b.test3());
A c = new C();
System.out.println(c.test3());
}
}

interface A {
void test1();

// 新增一个方法,其他实现类都需要重写不利于扩展
void test2();

// 默认方法
default String test3() {
System.out.println("接口中默认方法");
return "你好";
}
}

class B implements A {

@Override
public void test1() {

}

@Override
public void test2() {

}

@Override
public String test3() {
return "接口B重写了方法";
}
}

class C implements A {

@Override
public void test1() {

}

@Override
public void test2() {

}
}

2.2:默认方法的使用

1:实现类调用接口的默认方法

2:实现类重写接口的默认方法

3:静态方法

 3.1:静态方法格式:

interface 方法名:{

 修饰符 static 返回值类型  方法名:{

   方法体:

  }

}

package com.example.java8.inter;

public class Demo1Interface {
public static void main(String[] args) {
A b = new B();
System.out.println(b.test3());
A c = new C();
System.out.println(c.test3());
System.out.println(A.test4());
}
}

interface A {
void test1();

// 新增一个方法,其他实现类都需要重写不利于扩展
void test2();

// 默认方法
default String test3() {
System.out.println("接口中默认方法");
return "你好";
}

/**
* 静态方法
* @return
*/
static String test4(){
return "静态方法";
}
}

class B implements A {

@Override
public void test1() {

}

@Override
public void test2() {

}
@Override
public String test3() {
return "接口B重写了方法";
}
}

class C implements A {

@Override
public void test1() {

}

@Override
public void test2() {

}
}

3.2 静态方法的使用:

  静态方法不能被重写,只能通过接口类型调用:接口名.方法名

4 二者之间的区别:

 1:默认方法只能通过实现了调用,静态方法只能通过接口名调用

 2:默认方法可以被继承,实现类可以直接调用默认方法,也可以进行重写

 3:静态方法不可以被继承,实现类不可以直接调用默认方法,不可以进行重写

2: Steam Api

 2.1 集合处理数据的弊端:

当我们对集合进行操作时,除了最基本的新增,删除操作,最典型的就是遍历

package com.example.java8.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class SteamTest01 {
public static void main(String[] args) {
// 创建一个集合
List<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无");
list.add("杨幂");
list.add("你好");
System.out.println(list);
// 获取所有姓张的数据
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
if (!next.startsWith("张")){
iterator.remove();
}
}
System.out.println(list);
List<String> listSize = new ArrayList<>();
// 获取名字长度为3的数据
for (String item:list){
if (item.length()>=3){
listSize.add(item);
}
}
System.out.println(listSize);
}

}

针对上面不同的需求,需要对集合进行一遍遍的遍历,如果我们想进行更高效的遍历,需要jdk8中stream特性进行操作

2.2 stream-forEach方法

   forEach用来遍历流中的数据

void forEach(Consumer<? super T> action);

 该方法接口一个Consumer接口,会将每一个流交给函数处理

2.3 stream-count方法

count方法是用来计算流中元素的个数

long count();

该方法返回一个long值,代表个数

2.4 stream-filter方法

filter方法就是将一个流转换为另一个子集流

Stream<T> filter(Predicate<? super T> predicate);

该接口接受一个Predicate函数接口参数作为帅选条件

2.5 stream-limit方法

limit方法直接对流进行截取,支持前n个数据

Stream<T> limit(long maxSize);

参数传递是一个long值。

2.6 stream-spik方法

spik方法是跳过前面几个元素,然后转换为一个新的流

Stream<T> skip(long n);

2.7 stream-map方法

map方法是将流中的元素映射到另一个流中

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

该方法接口一个Function函数式接口,将T类型数据转换为R类型数据

2.8 stream-sorted方法

sorted方法是将元素进行排序

Stream<T> sorted();

Stream<T> sorted(Comparator<? super T> comparator);

一个是自然排序,一个是自定义排序

2.8 stream-distinct方法

distinct方法去掉元素中重复的数据

Stream<T> distinct();

2.9 stream-reduce方法

reduce将所有数据归纳成一个数据

T reduce(T identity, BinaryOperator<T> accumulator);

2.10 stream-mapToInt方法

mapToInt是将方法中Interger类型转换为int类型

2.11 stream-concat方法

concat方法是将2个流合并到一个流里面,他是一个静态方法

public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);

@SuppressWarnings("unchecked")
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
return stream.onClose(Streams.composedClose(a, b));
}

2.12 stream-结果数据到集合中

将结果转换为集合

将结果转换数组

2.13 stream-对流中数据进行聚合操作

当对流进行操作后,可以像数据库一样同时对流进行一些操作,如果最大值,最小值,平均值,统计数量

@Test
    public void  test3(){
        // 找到最大值
        Optional<entity1> max = Stream.of(new entity1(1, "你好"),
                        new entity1(2, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"))
                .collect(Collectors.maxBy((k, k1) -> k.getId() - k1.getId()));
        System.out.println(max.get());

        // 找到id为最小的数据
        Optional<entity1> min = Stream.of(new entity1(1, "你好"),
                        new entity1(2, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"))
                .collect(Collectors.minBy((k, k1) -> k.getId() - k1.getId()));
        System.out.println(min.get());

        // 计算出id的总和
        Integer sum = Stream.of(new entity1(1, "你好"),
                        new entity1(2, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"))
                .collect(Collectors.summingInt(s -> s.getId()));
        System.out.println(sum);

        // 计算出id的平均值
        Double avg = Stream.of(new entity1(1, "你好"),
                        new entity1(2, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"))
                .collect(Collectors.averagingInt(s -> s.getId()));
        System.out.println(avg);

        // 统计数量
        Long collect = Stream.of(new entity1(1, "你好"),
                        new entity1(2, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"))
                .filter(s -> s.getId() > 1).collect(Collectors.counting());
        System.out.println(collect);

    }

结果

entity1(id=40, name=ok)
entity1(id=1, name=你好)
50
10.0
4

2.14 stream-对流中数据进行分组

 @Test
    public void test4(){
        // 根据id进行分组
        Map<Integer, List<entity1>> map = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .collect(Collectors.groupingBy(entity1::getId));
        map.forEach((k,k1)->{
            System.out.println(k+"\n"+k1);
        });
        // id大于3的为优秀,否则为不合格
        Map<String, List<entity1>> map1 = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .collect(Collectors.groupingBy(entity1 -> {
                    return entity1.getId() > 3 ? "优秀" : "不合格";
                }));
        map1.forEach((k,k1)->{
            System.out.println(k+"\n"+k1);
        });
    }

1
[entity1(id=1, name=你好)]
3
[entity1(id=3, name=杨幂), entity1(id=3, name=赵丽颖)]
4
[entity1(id=4, name=知道)]
40
[entity1(id=40, name=ok), entity1(id=40, name=ok)]
优秀
[entity1(id=4, name=知道), entity1(id=40, name=ok), entity1(id=40, name=ok)]
不合格
[entity1(id=1, name=你好), entity1(id=3, name=杨幂), entity1(id=3, name=赵丽颖)]

进行多级分组

@Test
    public void test5(){
        // 根据id进行分组
        Map<Integer, Map<String, List<entity1>>> collect = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .collect(Collectors.groupingBy(entity1::getId, Collectors.groupingBy(entity1::getName)));
       collect.forEach((k,k1)->{
           k1.forEach((k2,k3)->{
               System.out.println(k+"\n"+k2+"\n"+k3);
           });
       });
        System.out.println("----------------------------");
        // id大于3的为优秀,否则为不合格
        Map<String, Map<String, List<entity1>>> collect1 = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .collect(Collectors.groupingBy(entity1::getName,
                        Collectors.groupingBy(entity1 -> entity1.getId() > 3 ? "优秀" : "不合格")));
        collect1.forEach((k,k1)-> {
            k1.forEach((k2, k3) -> {
                System.out.println(k + "\n" + k2 + "\n" + k3);
            });
        });
    }

1
你好
[entity1(id=1, name=你好)]
3
赵丽颖
[entity1(id=3, name=赵丽颖)]
3
杨幂
[entity1(id=3, name=杨幂)]
4
知道
[entity1(id=4, name=知道)]
40
ok
[entity1(id=40, name=ok), entity1(id=40, name=ok)]
----------------------------
知道
优秀
[entity1(id=4, name=知道)]
赵丽颖
不合格
[entity1(id=3, name=赵丽颖)]
你好
不合格
[entity1(id=1, name=你好)]
杨幂
不合格
[entity1(id=3, name=杨幂)]
ok
优秀
[entity1(id=40, name=ok), entity1(id=40, name=ok)]

2.15 stream-对流中数据进行拼接

  @Test
    public void test6(){
        // 对数据进行拼接
        String collect = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .map(entity1::getName)
                .collect(Collectors.joining());
        System.out.println(collect);

        // 按逗号进行拼接
        String collect1 = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .map(entity1::getName)
                .collect(Collectors.joining(","));
        System.out.println(collect1);


        // 按逗号进行拼接,并加上前缀和后缀
        String collect2 = Stream.of(new entity1(1, "你好"),
                        new entity1(3, "杨幂"),
                        new entity1(3, "赵丽颖"),
                        new entity1(4, "知道"),
                        new entity1(40, "ok"),
                        new entity1(40, "ok"))
                .map(entity1::getName)
                .collect(Collectors.joining(",","aaa","ccc"));
        System.out.println(collect2);

    }

你好杨幂赵丽颖知道okok
你好,杨幂,赵丽颖,知道,ok,ok
aaa你好,杨幂,赵丽颖,知道,ok,okccc
 

2.15 stream-串行流

穿行流也就是在一个线程上运行

2.16 stream-并行流

可以通过2种方式获取

集合中通过parallelStream获取

串行流中通过parallel获取 

如何使用

2.17 stream-for循环/并行流/串行流对比

package com.example.java8.stream;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.event.annotation.AfterTestMethod;
import org.springframework.test.context.event.annotation.BeforeTestMethod;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.LongStream;
import java.util.stream.Stream;

@SpringBootTest
public class StreamDemo2 {

    private static long times = 500000000;


    /**
     * for循环
     */
    @Test
    public void test(){
        System.out.println("普通for循环");
        long l = System.currentTimeMillis();
        int sum = 0;
        for (int i =0;i<times;i++){
            sum+=i;
        }
        System.out.println("普通for循环耗时:"+(System.currentTimeMillis()-l));
    }

    /**
     * 串行流
     */
    @Test
    public void test1(){
        System.out.println("串行流循环");
        long l = System.currentTimeMillis();
        LongStream.rangeClosed(0,times)
                .reduce(0,Long::sum);
        System.out.println("串行流循环耗时:"+(System.currentTimeMillis()-l));
    }


    /**
     * 并行流
     */
    @Test
    public void test2(){
        System.out.println("并行流循环");
        long l = System.currentTimeMillis();
        LongStream.rangeClosed(0,times).parallel()
                .reduce(0,Long::sum);
        System.out.println("并行流循环耗时:"+(System.currentTimeMillis()-l));
    }


}

结果

普通for循环
普通for循环耗时:310
串行流循环
串行流循环耗时:222
并行流循环
并行流循环耗时:65
 

2.17 stream-flatMap

flatMap方法主要是将一个流中每一个元素都转换为一个流,然后将这些流进行连接

结果

[1, 2, 3, 4, 22, 33, 55, 231, 213, 123, 12312, 123]

3:Optional类

optional是一个没有子类的工具类,,optional是一个可以为null的容器对象,它的主要作用是避免null检查,防止出现空指针

3.1 optional的创建方式

3.2 optional的基本使用

   /**
     * get()方法有值返回,没有值会抛出异常
     * isPresent() 方法返回true和false 是用来判定对象是否为null
     * orElse() 方法如果是空值,则返回方法中传递的参数
     */
    @Test
    public void test1(){
        Optional<String> o = Optional.of("你好");
        Optional<String> o1 = Optional.empty();

        if (o.isPresent()){
            String s1 = o.get();
            System.out.println(s1);
        }
        if (o1.isPresent()){
            String s2 = o1.get();
            System.out.println(s2);
        }else {
            System.out.println("空对象");
        }

        String s3 = o.orElse("知道了");
        String s4 = o1.orElse("收到");
        System.out.println(s3);
        System.out.println(s4);


    }

4:函数型接口

4.1 常用接口有那些

一 :Consumer  消费者接口

有参无返回值

@FunctionalInterface
public interface Consumer<T> {

/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);

使用:

andThen方法的使用

二:Function

有参有返回值 根据一个类型的数据得到另一个类型的数据,前者称为前者条件,后者为后置条件

@FunctionalInterface
public interface Function<T, R> {

/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);

使用:

三:Predicate

有参返回true/false

@FunctionalInterface
public interface Predicate<T> {

/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
 

使用:

四:Supplier 供给者结构

无参有返回值

@FunctionalInterface
public interface Supplier<T> {

/**
* Gets a result.
*
* @return a result
*/
T get();

使用

package com.example.java8.fun;

import java.util.function.Supplier;

public class SupplierTest {
    public static void main(String[] args) {
        String supplier = getSupplier(() -> "你好");
        System.out.println(supplier);

    }
    public static String getSupplier(Supplier<String> supplier){
        return supplier.get();
    }

}

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值