java8 :: 的用法

321 阅读1分钟

最近在看 java 8 Stream 的知识,看到了这样一种用法:

List<String> myList =
    Arrays.asList("a1", "a2", "b1", "c2", "c1");
    
myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);

当时就没看懂 :: 这种用法,于是自己去查找资料学习了一下。简单来说 :: 是 jdk 8 提供的一种方便访问目标类目标方法的方式。就是把方法作为参数传递到 Stream 中,使得 Stream 的每一个元素都可以使用该方法。


public class TestJdk1 {

  public static void printStr(String str) {

      System.out.println("当前元素为 :" + str);
  }

  public static void printStr(Object o) {

      System.out.println("当前元素为 :" + o);
  }

//    public void printStr(String str,String str1) {
//
//        System.out.println("当前元素为 :" + str + " 第二个参数为 :" + str1);
//    }
}

public class TestJdk2 {

   public static void main(String[] strings) {

       List list = new ArrayList();

       for (int i = 0; i < 10 ; i ++)
           list.add(i);
       // :: 是jdk 8 提供的 方便访问目标类的方法的快捷方式
       // 但是这种方式的目标是为了 将方法作为参数传递到stream 中去,是的stream 的每一个元素都传入到该方法中执行
       // 需要注意的是 这种方式不支持完整的方法的多态  也就是说 这个方法没有办法根据自己参数的情况来判断需要执行哪个方法;
       // 参数个数相同的情况下可以选择方法;参数个数不同的时候不行
       list.forEach(TestJdk1::printStr);

       System.out.println("==========================");

       Consumer<Object> consumer = TestJdk1::printStr;
       list.forEach(e-> consumer.accept(e));
   }
}

参见上面的 Consumer 的使用方式,可以通过下钻到 list.foreach 中可以查看源码:

f31f2ac3d67a2d9c12cfa3c4aadbd049_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png 在JDK8中,接口Iterable 8中默认实现了forEach方法,调用了 JDK8中增加的接口Consumer内的accept方法,执行传入的方法参数。