java8新特性

Java8新特性

接口中默认方法修饰为普通方法

lambda表达式

函数是式接口编程

方法与构造函数引用 类名称::方法名称

Stream接口


接口中默认方法修饰为普通方法

在JDK 1.8开始 支持使用static和default 修饰 可以写方法体,不需要子类重写。

方法:

普通方法 可以有方法体

抽象方法 没有方法体需要子类实现 重写。

注:接口中的属性的默认是public static final 、方法是public abstract

使用jdk8新特性可以定义普通方法,用default或者static修饰

public interface Jdk8Interface {
    void add();

   default void getDefault(){
        System.out.println("helo");
    }

    static void delStatic(){
        System.out.println("static");
    }
}

lambda表达式

lambda表达式的好处:简化了匿名内部类的调用

1.使用匿名内部类的形式调用接口

public class Test1 {
    public static void main(String[] args) {
        new OrderService() {
            @Override
            public void get() {
                System.out.println("get");
            }
        }.get();
    }

}

Lambda+方法引入代码变得更加精简

Lambda表达式的规范

使用Lambda表达式 依赖于函数接口

  1. 在接口中只能够允许有一个抽象方法

  2. 在函数接口中定义object类中方法

  3. 使用默认或者静态方法

  4. @FunctionalInterface 表示该接口为函数接口

Java中使用Lambda表达式的规范,必须是为函数接口

函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口

JDK中自带的函数接口:
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

我们也可以使用@FunctionalInterface修饰为函数接口

使用Lambda方法体中只有一条语句的情况下,在这时候我们不需要写(也可以不需要写return

使用forEach遍历集合

public class Test4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("chen");
        list.add("zhang");
        list.add("wang");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //升级版本
        list.forEach(s->{
            System.out.println(s);
        });
    }
}

小试牛刀:对集合进行排序

public class Test5 {
    public static void main(String[] args) {
        ArrayList<User> list = new ArrayList<>();
        list.add(new User("小米",20));
        list.add(new User("小华",15));
        list.add(new User("小陈",23));
        list.sort(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getAge()-o2.getAge();
            }
        });

        list.sort((o1,o2)->
                o1.getAge()-o2.getAge()
        );

        list.forEach((t)->{
            System.out.println(t.toString());
        });
    }
}

线程调用

new Thread(()-> System.out.println("我是子线程")).start();

什么是stream流

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

Stream :非常方便精简的形式遍历集合实现 过滤、排序等。

Mysql:select userName from xxwhere userName =‘xx’

Order by age limt(0,2)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nQ2jDxaN-1642494256991)(file:///C:\Users\chenchao\AppData\Local\Temp\ksohtml\wpsC252.tmp.jpg)]

Stream创建方式

parallelStream为并行流采用多线程执行

Stream采用单线程执行

parallelStream效率比Stream要高。


实体类

public class User {
private String username;
private int age;

    public User(String username, int age) {
        this.username = username;
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public User() {
    }

    public int getAge() {
        return age;
    }

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

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

    @Override
    public boolean equals(Object o) {

        if (o instanceof User){
            return username.equals(((User) o).username) && age==(((User) o).age);
        }else {
            return false;
        }
    }

    @Override
    public int hashCode(){
        return username.hashCode();
    }

}

实例

public class Test7 {
    public static void main(String[] args) {
        ArrayList<User> userEntities = new ArrayList<>();
        userEntities.add(new User("mayikt", 20));
        userEntities.add(new User("meite", 28));
        userEntities.add(new User("zhangsan", 35));
        userEntities.add(new User("xiaowei", 16));
        userEntities.add(new User("xiaowei", 16));
        /*串行流 Stream()  单线程
        * 并行流parsellerStream()   多线程*/
        Stream<User> stream = userEntities.stream();
//        将List集合转换为set集合类型
        Set<User> userSet = stream.collect(Collectors.toSet());
        userSet.forEach((user) -> {
            System.out.println(user.toString());
        });

    }
}

set集合底层依赖于map集合实现防重复key map集合底层基于equals比较防重复的

new FunctionUserEntity(list集合中的类型),String(key map)>

使用stream流将list集合转换为并遍历map集合

public class Test8 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        /**
         * new FunctionUserEntity(list集合中的类型),String(key map)>
         */
        Map<String, User> collect = stream.collect(Collectors.toMap(new Function<User, String>() {
            @Override
            public String apply(User user) {
                return user.getUsername();
            }
        }, new Function<User, User>() {
            @Override
            public User apply(User user) {
                return user;
            }
        }));
//遍历
        collect.forEach(new BiConsumer() {
            @Override
            public void accept(Object o, Object o2) {
                System.out.println(o+","+o2);
            }
        });
      
      
      //使用lamdba表达式
       Map<String, User> collect = stream.collect(Collectors.toMap(user -> user.getUsername(), user -> user));
//遍历
        collect.forEach((BiConsumer) (o, o2) -> System.out.println(o+","+o2));
    }
}

stream流求和

public class Test9 {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(10, 20, 30, 40, 50);
        /*Optional<Integer> reduce = stream.reduce(new BinaryOperator<Integer>() {

            @Override
            public Integer apply(Integer a1, Integer a2) {
                return a1 + a2;
            }
        });
        System.out.println(reduce.get());
*/

        Optional<Integer> reduce = stream.reduce((BinaryOperator<Integer>) (a1, a2) ->
                a1 + a2

        );
        System.out.println(reduce.get());

    }
}

取出最大值

public class Test10 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        Optional<User> max = stream.max(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println(max.get());
    }
}

StreamMatch匹配

anyMatch表示,判断的条件里,任意一个元素成功,返回true

allMatch表示,判断条件里的元素,所有的都是,返回true

noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

anyMatch  匹配一条含有的数据

public class Test11 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        boolean b = stream.anyMatch(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "hello".equals(user.getUsername());
            }
        });
        System.out.println(b);

    }
}

allMatch  匹配所有必须含有的数据

stream过滤器

public class Test12 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小华", 17));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
    stream.filter(new Predicate<User>() {
        @Override
        public boolean test(User user) {
            return "小华".equals(user.getUsername()) &&user.getAge()>18;
        }
    }).forEach((t)-> System.out.println(t));

    }
}

Stream limit和 skip(跳出)

public class Test13 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小华", 17));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        Stream<User> limit = stream.skip(2).limit(2);
        limit.forEach((t)->{
            System.out.println(t);
        });
    }

}

stream流排序

public class Test14 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("小华", 17));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        stream.sorted(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return -(o1.getAge()-o2.getAge());  //降序
            }
        }).forEach((t)->{
            System.out.println(t);
        });
    }
}

综合案列:对数据流的数据实现降序排列、小华 获取前两位

public class Test15 {
    public static void main(String[] args) {
        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("hello", 20));
        arrayList.add(new User("小华", 19));
        arrayList.add(new User("demo_zhangsan", 17));
        arrayList.add(new User("demo", 18));
        arrayList.add(new User("demo_lisi", 17));
        arrayList.add(new User("小美", 21));
        arrayList.add(new User("小张", 22));
        Stream<User> stream = arrayList.stream();
        //要求:对数据流的数据实现降序排列、小华 获取前两位
        stream.sorted(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o2.getAge()-o1.getAge();
            }
        }).filter(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return "demo".equals(user.getUsername());
            }
        }).limit(2).forEach((t)->{
            System.out.println(t);
        });

    }
}

串行流求速度

public class Test16 {
    public static void main(String[] args) {
        Instant start = Instant.now();
        long sum = 0;
        for (long i = 0; i < 500000000L; i++) { 
            sum += i;
        }

        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println("花费的时间是:" + Duration.between(start, end).toMillis());
    }
}

并行流

Instant start = Instant.now();
        LongStream longStream = LongStream.rangeClosed(0, 5000000000L);
        OptionalLong reduce = longStream.parallel().reduce(new LongBinaryOperator() {
            @Override
            public long applyAsLong(long left, long right) {
                return left + right;
            }
        });
        System.out.println(reduce);
        Instant end = Instant.now();
        System.out.println("花费的时间是:" + Duration.between(start, end).toMillis());

并行流与串行流区别

串行流:单线程的方式操作; 数据量比较少的时候。

并行流:多线程方式操作;数据量比较大的时候,原理:

Fork join 将一个大的任务拆分n多个小的子任务并行执行,

最后在统计结果,有可能会非常消耗cpu的资源,确实可以

提高效率。

注意:数据量比较少的情况下,不要使用并行流。


方法引入

什么是方法引入

方法引入:需要结合lambda表达式能够让代码变得更加精简。

  1. 匿名内部类使用

  2. Lambda调用匿名内部类

  3. 方法引入

方法引入

  1. 静态方法引入: 类名::(静态)方法名称

  2. 对象方法引入 类名:: 实例方法名称

  3. 实例方法引入 new对象 对象实例::方法引入

  4. 构造函数引入 类名::new

需要遵循一个规范:

方法引入 方法参数列表、返回类型与函数接口参数列表与返回类型必须

要保持一致。

Lambda: 匿名内部类使用代码简洁问题。

类型语法对应lambda表达式
构造器引用Class::new(args) -> new 类名(args)
静态方法引用Class::static_method(args) -> 类名.static_method(args)
对象方法引用Class::method(inst,args) -> 类名.method(args)
实例方法引用instance::method(args) -> instance.method(args)

方法引用提供了非常有用的语法,可以直接引用已有的java类或对象的方法或构造器。方法引用其实也离不开Lambda表达式,

与lambda联合使用 ,方法引用可以使语言的构造更加紧凑简洁,减少冗余代码。

方法引用提供非常有用的语法,可以直接引用已有的java类或者对象中方法或者构造函数,

方法引用需要配合Lambda表达式语法一起使用减少代码的冗余性问题。

构造器引入

静态方法引入

对象方法引入

实例方法引入

方法引入规则

方法引入实际上就是lambda表达式中直接引入的方法。

必须遵循规范:引入的方法参数列表返回类型必须要和函数接口参数列表、返回

类型保持一致。

public class Test1 {
    public static void main(String[] args) {
//    最原生的匿名内部类
      /*  MessageInterface messageInterface = new MessageInterface() {
            @Override
            public void get(Integer a) {
                System.out.println("get:a:"+a);
            }
        };
        messageInterface.get(1);*/

      /*  MessageInterface messageInterface1 =  (a)->{
          Test1.staticGet(a);
        };
        messageInterface1.get(2);*/

        MessageInterface staticGet = Test1::staticGet;
        staticGet.get(12);

    }

    public static void  staticGet(Integer a) {
        System.out.println("staticGet:a:" + a);
    }
}

实例方法引入

public class Test2 {
    public static void main(String[] args) {

        Test2 test2 = new Test2();
        MessageInterface messageInterface=()->
          test2.objGet();
        System.out.println(messageInterface.get());
        MessageInterface messageInterface1=test2::objGet;
    }

    public String objGet(){
        return "chen";
    }
}

对象实例

public class Test3 {
    public static void main(String[] args) {
/*        MessageInterFace2 messageInterFace2=()->{
            return new Message();
        };*/

        MessageInterFace2 messageInterFace2 = Message::new;
        System.out.println(messageInterFace2.getMsg());

        Function<String,Integer> s=(str)->{
            return str.length();
        };
        Function<String,Integer> str=String::length;


    }
}

Optional

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

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

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

判断参数是否为空

ofNullable(可以传递一个空对象)

Of(不可以传递空对象)

public class Test4 {

    public static void main(String[] args) {
        String username=null;
        Optional<String> optional = Optional.ofNullable(username);
        boolean present = optional.isPresent();//判断是否为空
        System.out.println(present);
    }
}

参数实现过滤,参数为空可以设定默认值

public class Test4 {

    public static void main(String[] args) {
        String username=null;
      /*  Optional<String> optional = Optional.ofNullable(username);
        boolean present = optional.isPresent();//判断是否为空
        System.out.println(present);*/

       /* String chen = Optional.ofNullable(username).orElse("chen");  //orElse设定默认值*/
        Optional<String> chen = Optional.ofNullable(username).filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.equals("chen");
            }
        });
        System.out.println(chen.isPresent());
    }
}

方法引入

public class Test5 {
    public static void main(String[] args) {
        String username=null;
        Optional<String> username1 = Optional.ofNullable(username);
        boolean present = username1.isPresent();
        if (present){
            System.out.println(username1.get());
        }
      /*  username1.ifPresent(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
//      方法引入
        username1.ifPresent(System.out::print);
        
    }
}

orElseGet()—与函数的接口的形式赋默认值

orELse()----直接传递默认值
return s.equals(“chen”);
}
});
System.out.println(chen.isPresent());
}
}


### 方法引入

public class Test5 {
public static void main(String[] args) {
String username=null;
Optional username1 = Optional.ofNullable(username);
boolean present = username1.isPresent();
if (present){
System.out.println(username1.get());
}
/* username1.ifPresent(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
});*/
// 方法引入
username1.ifPresent(System.out::print);

}

}


orElseGet()---与函数的接口的形式赋默认值

orELse()----直接传递默认值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值