posts - 22, comments - 32, trackbacks - 0, articles - 73
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
函数式接口的特征

1、三种方法

  • 唯一的抽象方法
  • 使用default定义普通方法(默认方法),通过对象调用。
  • 使用static定义静态方法,通过接口名调用。

2、一个新注解@FunctionInterface

  • 注解@FunctionalInterface告诉编译器这是一个函数式接口,明确这个函数中只有一个抽象方法,当你尝试在接口中编写多个抽象方法的时候编译器将不允许,但是可以有多个非抽象方法。

  • 不过Object类的方法可以定义为抽象方法,因为接口的实现类一定是Object的子类

  • 如果接口被标注了@FunctionalInterface,这个类就必须符合函数式接口的规范

  • 即使一个接口没有标注@FunctionalInterface,如果这个接口满足函数式接口规则,依旧被当作函数式接口。

3JDK 1.8 新增加的函数接口包
   

    java.util.function.*
    java.util.function 它包含了很多接口,用来支持 Java的 函数式编程,它们大致分为五类:

    
   

 4、代码样例

    
    /**
     *JDK 8 函数式接口  Supplier、Function、Consumer、Predicate
     *
     * @param args
     * @throws Exception
     
*/

    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor executor = (ThreadPoolExecutor)newFixedThreadPool(10);
        //1:JDK8以前,通过匿名内部类实现函数式接口
        executor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("JDK8以前,通过匿名内部类实现函数式接口");
            }
        });
        //2:JDK8以后可以使用lambda 表达式来实现,lambda表达式就是为了优化匿名内部类而生(分开写效果)
        Thread thread = new Thread(() -> System.out.println("task running !"));
        Runnable r = () -> System.out.println("JDK8以后可以使用lambda 表达式来实现,lambda表达式就是为了优化匿名内部类而生(分开写效果)!");
        executor.submit(r);
        //3:合并起来效果
        executor.submit(() -> {
            System.out.println("JDK8以后可以使用lambda 表达式来实现,lambda表达式就是为了优化匿名内部类而生!");
        });

        //4:其它 Supplier、Function、Consumer、Predicate 都可以用lambda 表达式来实现
        Supplier<String> supplier = () -> "我是SuSupplier";
        Supplier<Integer> supplier2 = () -> new Integer(1);
        System.out.println("supplier=" + supplier.get() + ";supplier2=" + supplier2.get());

        //5: Function功能型函数式接口 Function<T, R> 接受一个输入参数T,返回一个结果R
        Function<String,Integer> function=str -> Integer.parseInt(str);
        Function<Integer,String> fun2 = item -> item+"";
        System.out.println("输入字符型 1 返回int型结果:"+function.apply("1"));
        System.out.println("输入整型 1 返回字符型结果:"+fun2.apply(2));

        //6: Consumer 一个接受单个输入参数并且不返回结果的操作。 与大多数其他函数接口不同, Consumer接口期望通过接受参数,改普通对象引用值(说明白点就是对原来的值进行加工,注意返回值 void)
        Consumer<StringBuffer> consumer= sb->sb.append("-yyy");
        StringBuffer sb1=new StringBuffer().append("111");
        consumer.accept(sb1);
        //改变sb的内部引用值
        System.out.println("=========s="+sb1.toString());

        //7: Predicate<T> 断言型接口常用于集合的过滤,得到一个新的集合 Stream filter(Predicate<? super T> predicate);
        Predicate<Integer> predicate = age -> age > 18;
        Predicate<String> predicate2 = str -> str != null;
        System.out.println(predicate.test(19));
        System.out.println(predicate2.test(null));
        //我们常用集合过滤类就是对这个接口实现类 其中 filter(Predicate<? super T> predicate) 用的就是这个接口
        List<String> list= Lists.newArrayList("1","2","2","3","4","4","8");
        list.stream().map(s -> Long.parseLong(s)).distinct().filter(s -> s < 10).collect(Collectors.toList()).forEach(-> System.out.println(u));

        //总结,以上的例子其实都是JDK8 lambda 表达式简洁的写法,而且全是合并写的,并没有分开步骤写(所有函数性接口,都可以用lambda 表达式简洁写法)

        
//关闭线程池
        executor.shutdownNow();
    }

只有注册用户登录后才能发表评论。


网站导航: