栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java8新特性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java8新特性

1. lambda表达式

接口实现
    第一种方式:创建实现类 ,用实现类进行接口的实现
    第二种方式:通过匿名内部类进行进行实现

1.1  内部类 与 lambda表达式的区别

基于匿名内部类实现的方式,特点:
内部类:
    1 代码比较复杂,比较繁琐
    2 匿名内部类,类,执行过程中,需要进行编译,------》花费时间比较长
    3 需要编译,形成class文件,在硬盘上占用空间
    4匿名内部类 实现接口,接口中可以有多个抽象方法
lambda表达式:
    1 代码简化,不形成类,不需要编译,不需要占用硬盘空间(不生成.class文件)    
    2 lambda表达式,只能有一个抽象方法

1.2 lambda表达式使用

lambda表达式:
    格式:
    实现的接口中方法的形参  指向    方法体(方法逻辑)
        ()     ->       {}

对lambda表达式简化

    格式:()->{}
    1 参数部分的简化:
        如果方法是无参方法,()不能省略
        如果方法是有参数的方法,参数数据类型可以省略
        注意:如果参数有多个,数据类型同时省略
        注意:如果参数有一个,数据类型可以省略,并且在数据类型省略的同时,()可以省略
    
    2 方法的方法体简化
        有返回值的方法,无返回值方法
        无返回值方法:如果方法中只有一句方法的逻辑代码,{}可以省略
        有返回值的方法:如果方法只有一句代码,省略return关键词,
        在return省略的前提下,{}可以省略的

1.2.1 对接口抽象方法实现使用
  • 无参数列表,无返回值
    public interface Cat {
        void eat();
    }
    -------------->
    public class Test1 {
        public static void main(String[] args) {
            
            Cat cat = () -> {
                System.out.println("我是eat实现");
            };
            cat.eat();
            
            Cat cat1 = () -> System.out.println("我是eat实现");
            cat1.eat();
         }

       
      Cat cat1 = () -> System.out.println("我是eat实现");
      cat1.eat();

  • 参数列表,无返回值
     
            Person p = (String name, int age) -> {
                System.out.println("名字是:"+name + "年龄是:" + age);
            };
            p.call("张三", 12);
    
            
            Person p1 = (name, age) ->{
                System.out.println("名字是:"+name + "年龄是:" + age);
            };
            p1.call("张三", 12);
    
            //最终写法
            Person p2 = (name, age) -> System.out.println("名字是:"+name + "年龄是:" + age);
            p2.call("张三", 12);

     如果有多个参数,可以省略参数数据类型;
     如果方法体中只有一句代码,可以省略{};

  • 有参数列表,有返回值
            
            shape shape1 = (String b)->{
                return "面积为" +b;
            };
            String area = shape1.area("12平方公里");
            System.out.println(area);
            
            shape shape2 = b -> {
                return "面积为" +b;
            };
            shape2.area("12平方公里");
    
            //最终写法
            shape shape3 = b -> "面积为"+b;
            shape2.area("12平方公里");
    

    如果只有一个参数,可以省略参数数据类型,并且可以省略参数列表括号;
    如果方法体只有一句代码,可以省略{},如果含有return,也可以省略retren 

1.2.2 方法的引用
  • 静态方法的引用

                在lambda表达式中,进行方法引用,逻辑实现中的方法的参数和接口中要实现的方法的参数保持一致

    对静态方法的引用:
    格式:类名::方法名

public interface Sum {
    
    int add(int a, int b);
}
------------------------------->
public class SumUtil {
    
    public static int addMethod(int a, int b){
        return a + b;
    }
}
------------------------------------------>

Sum sum1 = (a, b) -> SumUtil.addMethod(a,b);
System.out.println("计算结果为:" + sum1.add(10,20));
//简化写法
Sum sum = SumUtil::addMethod;
System.out.println("计算结果为:" + sum.add(10,20));
  • 实例方法的引用 

lambda表达式对实例方法的引用:
格式:new 构造方法 ::实例方法名
         对象::实例方法名

public interface Change {
    
    String toUpper(String s);
}
-------------------------------------->
public class ChangeUtil {
    
    public String upper(String str){
        String result = "";
        byte[] chars = str.getBytes();
        for (byte c:chars) {
            result += (char)(c-32);
        }
        return result;
    }
}
-------------------------------------->
        
        Change change1 = s -> new ChangeUtil().upper(s);
        System.out.println(change1.toUpper("hello"));
        //简化写法
        Change change = new ChangeUtil()::upper;
        System.out.println(change.toUpper("hello"));
  •  类对实例方法引用

方法的引用
    类对实例方法引用
        类名::实例方法

public class Dog {
    private String name;
    private Integer age;
    private String type;

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

    public Dog() {
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", type='" + type + ''' +
                '}';
    }
}
------------------------------------------------>

public interface CreateDog {
    //创建Dog对象
    Dog creDog();
}
------------------------------------------------->
        
        CreateDog cc = () -> new Dog();
        System.out.println(cc.creDog());
        //简化写法
        CreateDog cc1 = Dog :: new;
        System.out.println(cc1.creDog());
  •  数组方法引用
public interface CreateArray {
    int[] create(int length);
}
--------------------------------->
        
        CreateArray ca = (int length) -> new int[length];
        System.out.println(ca.create(5));
        //简化写法
        CreateArray ca1 = int[]::new;
        System.out.println(ca1.create(5));
2.常用接口

java8 新特性
    接口中默认是抽象方法和常量 
    接口中可以出现方法体
    1 方法有方法体,需要使用default关键词进行修饰
        default void a(){
            接口中default修饰的方法,可以有方法体,并且实现类可以有选择性的重写
        }
    2 接口中可以有静态方法
     static void a(){
        }

2.1 Predicate (条件判断的接口)
import java.util.function.Predicate;

public class Test02 {
    public static void main(String[] args) {
        
        Predicate pre = new Predicate(){
            @Override
            public boolean test(Integer integer) {
                return integer > 100;
            }
        };
        System.out.println(pre.test(150));

        
        Predicate pre1 = integer -> integer > 100;
        System.out.println(pre1.test(150));

        
        Predicate pre2 = integer -> integer > 10;
        Predicate pre3 = integer -> integer > 90;
        //50是否大于10 并且 50是否大于90
        
        System.out.println(pre2.and(pre3).test(50));

        
        Predicate pre4 = integer -> integer > 10;
        Predicate pre5 = integer -> integer > 90;
        //50是否大于10 或者 50是否大于90
        System.out.println(pre4.or(pre5).test(50));

        
        Predicate pre6 = integer -> integer > 10;
        //20是否大于10,在进行取反
        System.out.println(pre6.negate().test(20));
    }
}
2.2 Comparator(比较接口)
        

        TreeSet set = new TreeSet<>(new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });

        TreeSet set1 = new TreeSet<>( (o1,o2) -> o1-o2);
        set1.add(20);
        set1.add(10);
        set1.add(35);
        set1.add(30);
        System.out.println(set1);
  2.3 Function(类型转换接口)

        第一个泛型类型的数据转成第二个泛型类型的功能 

        
        Function fun = new Function() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        };
        Integer apply = fun.apply("123");
        System.out.println(apply instanceof Integer); // true

//        Function fun1 = (String s) -> {return Integer.parseInt(s);};
//        Function fun1 = s ->  Integer.parseInt(s);
        Function fun1 = Integer::parseInt;
        Integer apply1 = fun1.apply("234");
        System.out.println(apply1 instanceof Integer); // true
3 lambda表达式+接口应用场景 3.1 stream(集合中的流)

Java8 中添加了一个新的接口类 Stream,相当于高级版的 Iterator,它可以通过 Lambda 表达式对集合进行大批量数据操作,或 者各种非常便利、高效的聚合数据操作。 

在 Java8 之前,我们通常是通过 for 循环或者 Iterator 迭代来重新排序合并数据,又或者通过重新定义 Collections.sorts 的 Comparator 方法来实现,这两种方式对于大数据量系统来说,效率并不是很理想。Stream 的聚合操作与数据库 SQL 的聚合操作 sorted、filter、map 等类似。我们在应用层就可以高效地实现类似数据库 SQL 的 聚合操作了,而在数据操作方面,Stream 不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高数据 的处理效率。
 


    水开始流的位置:开始流
    水流流过的位置:中间流
    水流到山脚下结束:结束流
注意:流都是一次性

    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(100);
        list.add(25);
        list.add(63);
        list.add(5);
        list.add(105);
        list.add(98);
        list.add(69);
        list.add(25);
}
  •  filter 判断数据是否满足条件
     
        Stream stream = list.stream();

        

        

        stream.filter(integer -> integer>50 ).forEach(System.out::println);

  •  toArray() 将数据保存到数组中
        

        Object[] objects = stream.filter(integer -> integer > 50).toArray();
        System.out.println(Arrays.toString(objects)); //[100, 63, 105, 98, 69]

  • distinct 去重
     

        Object[] objects = stream.distinct().toArray();
        System.out.println(Arrays.toString(objects));

  •  sorted 排序,默认降序
        
        Object[] objects = stream.sorted().toArray();
        System.out.println(Arrays.toString(objects));

 自己指定排序条件

        
        Object[] objects = stream.sorted((o1, o2) -> o2 - o1).toArray();
        System.out.println(Arrays.toString(objects));
  • 中间流进行多次操作,排序 去重 指定条件的数据的显示
        
        Object[] objects = stream.distinct().sorted().filter(integer -> integer >25).toArray();
        System.out.println(Arrays.toString(objects)); //[63, 69, 98, 100, 105]

  •   数据 指定条数数据的展示
        
        Object[] objects = stream.distinct().sorted().limit(3).toArray();
        System.out.println(Arrays.toString(objects));

  •  max() 最大值、min() 最小值 
        
//        Integer integer = stream.distinct().max((o1, o2) -> o1 - o2).get();
//        System.out.println(integer); //105
        Integer integer = stream.distinct().min((o1, o2) -> o1 - o2).get();
        System.out.println(integer); //5

 

  •  map 转成其他数据类型
        
        //将所有数据都拼接abc
        Object[] objects = stream.distinct().map(s -> s + "abc").toArray();
        System.out.println(Arrays.toString(objects)); //[100abc, 25abc, 63abc, 5abc, 105abc, 98abc, 69abc]

doubleValue(全部转换成double类型),longValue(全部转换成long类型),intValue(全部转换成int类型)

        
//        double[] doubles = stream.mapToDouble(Integer::doubleValue).toArray();
//        System.out.println(Arrays.toString(doubles)); //[100.0, 25.0, 63.0, 5.0, 105.0, 98.0, 69.0, 25.0]
//        long[] longs = stream.mapToLong(Integer::longValue).toArray();
//        System.out.println(Arrays.toString(longs)); //[100, 25, 63, 5, 105, 98, 69, 25]
        int[] ints = stream.mapToInt(Integer::intValue).toArray();
        System.out.println(Arrays.toString(ints)); //[100, 25, 63, 5, 105, 98, 69, 25]
  • reduce 数据运算
            
            //将数组中所有数据相加
            Integer integer = stream.reduce((integer1, integer2) -> integer1 + integer2).get();
            System.out.println(integer);

  • 对流中数据进行判断,是否所有的都满足条件  (allMatch)、对流中数据进行判断,是否任意一条数据的都满足条件(anyMatch)、 据进行判断,是否所有数据的都不满足条件  (noneMatch)

        
//        boolean b = stream.allMatch(integer -> integer > 26);
//        System.out.println(b); // false

//        boolean b = stream.anyMatch(integer -> integer > 26);
//        System.out.println(b); // true

        boolean b = stream.noneMatch(integer -> integer > 26);
        System.out.println(b); // false
  •  count()数据个数的统计
        
        long count = stream.distinct().count();
        System.out.println(count);

4. 可变长参数

        方法定义时,可以给方法进行参数个数的不固定个数的指定

    public static void main(String[] args) {
        List list = Arrays.asList(1, 2, 3, 4, 5, 6);
        System.out.println(list);
}

我们从上面的例子可以看出,可变长参数,可以传到多个参数,如果我们不清楚传递多个少个参数,我们可以使用可变长参数。
注意:
1. 一个方法中只能有一个可变长参数,并且可变长参数必须在参数列表最后位置 ;
2. 可变长参数,传入到方法中,它是将所有参数都放到数组中,因此我们方法获取到的可变长参数是一个数组,数组里面存放的我们传入的数据;

public class demo02 {
    
    public static void main(String[] args) {
        me(1,2,3,4,5);
        me("a","b","c","d");
        me(new Student("zs",12), new Student("ls",36),  new Student("ww",43));

    }

    
    public static  void me(T... arr){
        System.out.println(Arrays.toString(arr));
    }

}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886307.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号