服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java双冒号(::)运算符使用详解

Java双冒号(::)运算符使用详解

2022-01-05 11:07会飞的鱼干干 Java教程

之前没用过::这个东西,今天看flink的时候发现官网有个例子用到了这个符号,本文就详细的来介绍一下Java双冒号(::)运算符使用详解,感兴趣的可以了解一下

1.说明

之前没用过::这个东西,今天看flink的时候发现官网有个例子用到了这个符号, 本着求知欲去百度查了一番,没找到能说到我心里去的解释,本着求知欲的态度,我去了官网看了看. java ::

2.先来说下@FunctionalInterface

java8 lambda 内部接口需要@FunctionalInterface这个注解,这个注解是一个说明性质的注解,被@FunctionalInterface注解的接口只能由一个抽象方法,@FunctionalInterface只能用于注解接口而不能用在class以及枚举上.
被@FunctionalInterface注解的符合规则的接口,可以用lambda表达式. 下面举一个例子:

?
1
2
3
4
5
6
7
8
9
10
11
public class Main {
    public static void pr(String s){
        System.out.println(s);
    }
    public static void main(String[] args) throws Exception {
 
        List<String> list = Arrays.asList("aaaa", "bbbb", "cccc");
        list.forEach(s -> System.out.println(s));
 
    }
}

所以说,@FunctionalInterface用于lambda样式说明.

3. 下面来讲讲这个 "::"是干嘛的

"::"官网对这个符号的解释是方法引用,也就是引用一个方法的意思,英文名称Method References
lambda expressions 可以用来创建一匿名的方法, 这个匿名的方式你需要自己实现.

?
1
2
3
4
5
6
7
1. list.forEach(new Consumer<String>() {
         @Override
         public void accept(String s) {
             System.out.println(s);
         }
     });
2. list.forEach(s -> System.out.println(s));

上面两种写法是一样的,下面就是lambda表达式.

上面说了lambda表达式你需要自己实现,但是有些时候这不是必要的,比如你的项目里某个地方存在了一个符合当前逻辑的lambda表达式的方法, 那么我是否可以直接拿来用?, 答案是可以, 程序追求的就是不重复极简的思想, 既有则拿来用即可,为什么还要自己实现呢. Method References 就是用来做这件事的.

在看下面的例子之前读者需要知道java 比较器,否则看不懂代码.

4. 建立一个Person类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Person implements Comparable<Person>{
    public String name;
    public int age;
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public static int compareByAge(Person a, Person b) {
        return a.compareTo(b);
    }
 
    @Override
    public int compareTo(Person o) {
        if (this.age > o.age){
            return -1;
        }else{
            return 1;
        }
    }
}

4:构建多个person对象,放入数组中,然后对数组中的person重新排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test {
 
    //编写Comparator,Person的age
    private static final Comparator<Person> COMPARATOR = new Comparator<Person>() {
        public int compare(Person a, Person b) {
            return a.compareTo(b);//运用User类的compareTo方法比较两个对象
        }
    };
 
    public static void main(String[] args) {
        Person one = new Person("张三",50);
        Person two = new Person("李四",100);
        ArrayList<Person> array = new ArrayList<>();
        array.add(one);
        array.add(two);
        Collections.sort(array,COMPARATOR);
        System.out.println(array);
    }
}
//输出结果:
//[Person{name='李四', age=100}
//Person{name='张三', age=50}]

仔细看上面的代码,重点在Collections.sort(array,COMPARATOR);这一行,sort接收两个参数,第一个是要被排序的数组,第二个是一个比较器对象Comparator,其源码如下,我只粘贴了必要的部分.

?
1
2
3
4
**@FunctionalInterface**
public interface Comparator<T> {
    int compare(T o1, T o2);
}

@FunctionalInterface我们知道,被这个注解修饰的接口可以用lambda表达式的.

所以我们将class Test改成下面的样子:

?
1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
    public static void main(String[] args) {
        Person one = new Person("张三",50);
        Person two = new Person("李四",100);
        ArrayList<Person> array = new ArrayList<>();
        array.add(one);
        array.add(two);
        Collections.sort(array, (a, b) -> a.compareTo(b));
        System.out.println(array);
    }
 
}

 注意:下面是lambda写法,和正常传统写法

?
1
2
3
4
5
6
7
8
Collections.sort(array, (a, b) -> a.compareTo(b));
和下面的等效
Collections.sort(array, new Comparator() {
@Override
public int compare(Person a, Person b) {
return a.compareTo(b);
}
});

5:揭秘 "::"符号

到这里其实我们上面的功能已经完成了,我们来分析一下代码.
1:构造了两个对象
2:把对象放入了数组
3:Collection.sort(array,Comparator<T>) 对数组进行排序

关键点在于:Comparator<T> 比较器,它是一个被@FunctionalInterface修饰的接口,我们一般成为函数式接口.
因此,Collection.sort(array,Comparator<T>) ,对于第二个参数Comparator<T>,我们可以传入一个匿名实现类,然后实现里面的 int compare(T o1, T o2) 方法,也可以写成lambda表达式的样子,到这里如果你都懂了,那么接下来就好说了,如果没明白,回头接着看,相信自己骚年. 下面我们重点看lambda方式的写法,这和"::"息息相关

Collections.sort(array, (a, b) -> a.compareTo(b));

  1. **(a, b) -> a.compareTo(b)**这个其实就是匿名函数, 该函数的参数分别是Person a, Person b
  2. a.compareTo(b) 是该匿名函数的逻辑,

也即是说我们写出来的这个匿名函数有两个参数,以及一个调用compareTo的函数体,到这里其实结束了,一开始我们就说了,符号"::"的意义就是用一个已经存在的函数代替我们lambda表达式中的函数体,只要这个存在的函数和lambda函数体的函数格式一致就行了. 格式其实就是参数个数,和参数类型下面是新的class Test揭示了答案

?
1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
    public static void main(String[] args) {
        Person one = new Person("张三",50);
        Person two = new Person("李四",100);
        ArrayList<Person> array = new ArrayList<>();
        array.add(one);
        array.add(two);
        Collections.sort(array, Person::compareByAge);//写法一
     // Collections.sort(array, one::entyMethod);//写法二
       System.out.println(array);
    }
}

附官网的一句话:
Because this lambda expression
invokes an existing method,
you can use a method reference
**instead of** a lambda expression

?
1
2
Collections.sort(array, Person::compareByAge);
Collections.sort(array, one::entyMethod);

这两种写法都是可行的.

6.0 方法引用的支持如下

Java双冒号(::)运算符使用详解

我们上面讲了静态方法,和类方法的代替方式,至于其他的这里不讲了,主要是我要去吃饭了.

到此这篇关于Java双冒号(::)运算符使用详解的文章就介绍到这了,更多相关Java双冒号(::)内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_36066039/article/details/120225882

延伸 · 阅读

精彩推荐
  • Java教程小米推送Java代码

    小米推送Java代码

    今天小编就为大家分享一篇关于小米推送Java代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...

    富贵稳中求8032021-07-12
  • Java教程20个非常实用的Java程序代码片段

    20个非常实用的Java程序代码片段

    这篇文章主要为大家分享了20个非常实用的Java程序片段,对java开发项目有所帮助,感兴趣的小伙伴们可以参考一下 ...

    lijiao5352020-04-06
  • Java教程升级IDEA后Lombok不能使用的解决方法

    升级IDEA后Lombok不能使用的解决方法

    最近看到提示IDEA提示升级,寻思已经有好久没有升过级了。升级完毕重启之后,突然发现好多错误,本文就来介绍一下如何解决,感兴趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一个注意事项

    Java8中Stream使用的一个注意事项

    最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,但在使用中遇到了一个非常重要的注意点,所以这篇文章主要给大家介绍了关于Java8中S...

    阿杜7482021-02-04
  • Java教程Java BufferWriter写文件写不进去或缺失数据的解决

    Java BufferWriter写文件写不进去或缺失数据的解决

    这篇文章主要介绍了Java BufferWriter写文件写不进去或缺失数据的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java实现抢红包功能

    Java实现抢红包功能

    这篇文章主要为大家详细介绍了Java实现抢红包功能,采用多线程模拟多人同时抢红包,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙...

    littleschemer13532021-05-16
  • Java教程xml与Java对象的转换详解

    xml与Java对象的转换详解

    这篇文章主要介绍了xml与Java对象的转换详解的相关资料,需要的朋友可以参考下...

    Java教程网2942020-09-17
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    这篇文章主要介绍了Java使用SAX解析xml的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下...

    大行者10067412021-08-30