标签: functional-interface

转换Java功能接口

一如既往,我正在查看JDK 8源代码并发现非常有趣的代码:

@Override
default void forEachRemaining(Consumer<? super Integer> action) {
    if (action instanceof IntConsumer) {
        forEachRemaining((IntConsumer) action);
    } 
}
Run Code Online (Sandbox Code Playgroud)

问题是:怎么Consumer<? super Integer>可能是一个实例 IntConsumer?因为他们处于不同的等级.

我已经制作了类似的代码片段来测试:

public class InterfaceExample {
    public static void main(String[] args) {
        IntConsumer intConsumer = i -> { };
        Consumer<Integer> a = (Consumer<Integer>) intConsumer;

        a.accept(123);
    }
}
Run Code Online (Sandbox Code Playgroud)

但它抛出ClassCastException:

Exception in thread "main" 
    java.lang.ClassCastException: 
       com.example.InterfaceExample$$Lambda$1/764977973 
     cannot be cast to 
       java.util.function.Consumer
Run Code Online (Sandbox Code Playgroud)

你可以在java.util.Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)找到这段代码.

java lambda classcastexception java-8 functional-interface

25
推荐指数
3
解决办法
4182
查看次数

是否可以声明供应商<T>需要抛出异常?

所以我试图重构以下代码:

/**
 * Returns the duration from the config file.
 * 
 * @return  The duration.
 */
private Duration durationFromConfig() {
    try {
        return durationFromConfigInner();
    } catch (IOException ex) {
        throw new IllegalStateException("The config file (\"" + configFile + "\") has not been found.");
    }
}

/**
 * Returns the duration from the config file.
 * 
 * Searches the log file for the first line indicating the config entry for this instance.
 * 
 * @return  The duration.
 * @throws FileNotFoundException If …
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface

22
推荐指数
4
解决办法
2万
查看次数

'Comparable <T>应该是'功能界面'吗?

功能接口的定义是"功能接口是一个只有一个抽象方法的接口(除了Object的方法),因此代表一个单一的功能契约."

根据这个定义,Comparable<T>它绝对是一个功能界面.

lambda表达式的定义是"lambda表达式就像一个方法:它提供了一个形式参数列表和一个正文 - 一个表达式或块 - 用这些参数表示."

lambda表达式的评估产生功能接口的实例.

因此,lambda表达式的目的是通过实现功能接口的单个​​功能来创建功能接口的实例.即.允许使用单个函数创建实例.

让我们来看看Comparable<T>,这个界面是否设计用作单一功能?即.它是否仅用于创建具有此单一功能的实例?

Comparable<T>以"This接口开头的文档对每个实现它的类的对象施加了一个总排序.这个排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法."

上面的句子清楚地表明,Comparable<T>它不是设计用作单个函数,而是总是由一个类实现,它通过添加这个单个函数对其实例具有自然顺序.

这意味着它不是设计为使用lambda表达式创建的?

关键是我们不会有任何仅仅是可比较的对象,它意味着要实现,因此用作类的附加功能.

那么,Java语言中是否有一种方法Comparable<T>可以防止创建lambda表达式?接口的设计者是否可以决定该接口是否由类实现,而不是通过使用lambda表达式使用此单一方法创建为实例?

仅仅因为接口恰好有一个抽象方法,它不应该被视为一个功能接口.

也许,如果Java提供像NotFunctional这样的注释,编译器可以检查该接口是否不用于创建lambda表达式,例如.

@NotFunctional
public interface Comparable<T> { public int compareTo(T t); }
Run Code Online (Sandbox Code Playgroud)

java lambda interface java-8 functional-interface

22
推荐指数
2
解决办法
4910
查看次数

当Comparator有两个抽象方法时,它如何成为一个功能接口?

在Java 8中,@FunctionalInterface引入了注释以表示任何具有一个抽象方法作为功能接口的接口.引入它的原因之一是指示用户(程序员),lambda表达式可以在功能接口的上下文中使用.

Comparator接口都被注解@FunctionalInterface.但是,两种方法都是抽象的.

int compare(T o1, T o2);
Run Code Online (Sandbox Code Playgroud)

boolean equals(Object obj);
Run Code Online (Sandbox Code Playgroud)

在文档中FunctionalInterface,它被明确提及为

从概念上讲,功能界面只有一种抽象方法.

这个equals方法不是被认为是抽象的吗?

java comparator java-8 functional-interface

22
推荐指数
2
解决办法
3650
查看次数

有没有办法在24以下的Android API上使用Java 8功能接口?

我可以使用retrolambda来启用Android API级别<24的lambdas.这样可行

myButton.setOnClickListener(view -> Timber.d("Lambdas work!"));
Run Code Online (Sandbox Code Playgroud)

这也有效

Runnable runLater = () -> Timber.d("Lambdas work!");
runLater.run();
Run Code Online (Sandbox Code Playgroud)

但是这个没有

Consumer<Integer> runLaterWithInt = (Integer i) -> Timber.d("i = " + i);
runLaterWithInt.accept(3);
Run Code Online (Sandbox Code Playgroud)

最后一个适用于Android API Level 24,但在其他设备上,此代码会导致崩溃

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$$Lambda$1
Run Code Online (Sandbox Code Playgroud)

我试图启用Java 8.而不是使用retrolambda.前两个代码示例仍然有效,尽管butterknife停止工作.https://developer.android.com/preview/j8-jack.html#configuration这里ava.util.function被认为是支持的,但在运行第三个时,我仍然得到一个崩溃,这一次却是有一点不同

java.lang.NoClassDefFoundError: com.retrolambdatry.MainActivity$-void_onCreate_android_os_Bundle_savedInstanceState_LambdaImpl1
Run Code Online (Sandbox Code Playgroud)

java lambda android functional-interface retrolambda

21
推荐指数
2
解决办法
6780
查看次数

功能接口继承Quirk

我有一个我已经使用了一段时间的自定义界面,看起来像这样:

public interface Function<T, R> {
    R call(T input);
}
Run Code Online (Sandbox Code Playgroud)

我想用Java Function和Guava 来改进这个接口Function,同时保持它FunctionalInterface.我以为我有完美的安排:

@FunctionalInterface
public interface Function<T, R> extends
        java.util.function.Function<T, R>,
        com.google.common.base.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}
Run Code Online (Sandbox Code Playgroud)

两个超级apply()接口都声明了相同的方法,该方法已在我的界面中实现,只留下抽象call()方法.奇怪的是,它不会编译,告诉我

"@FunctionalInterface"注释无效; 函数<T,R>不是功能接口

更奇怪的是,以下变化编译得很好:

@FunctionalInterface
public interface Function<T, R> extends
        java.util.function.Function<T, R> {

    R call(T input);

    @Override
    default R apply(T input) {
        return call(input);
    }
}
Run Code Online (Sandbox Code Playgroud)

@FunctionalInterface
public interface Function<T, R> extends
        com.google.common.base.Function<T, R> …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 default-method functional-interface

19
推荐指数
1
解决办法
3084
查看次数

为什么Java 8中的功能接口有一个抽象方法?

正如我们在Java 8中所知,引入了功能接口的概念.功能接口有一种abstract方法,可以使用多种默认或静态方法.

但为什么Functional接口只有一个抽象方法呢?如果Interface有多个抽象方法,为什么这不是一个功能接口?

java java-8 functional-interface

18
推荐指数
3
解决办法
1万
查看次数

Java lambda只抛出表达式而不是语句式

在Java(目前使用Java 8)中,我可以编写这个并且所有编译都很好:

Supplier<Long> asd = () -> {
    throw new RuntimeException();
};
Run Code Online (Sandbox Code Playgroud)

但是,我不能这样写:

Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么Java的实现不允许这样的样式(表达式lambda)和只有语句/代码块样式lambda?

我的意思是,由于lambda 抛出RuntimeException,为什么JDK不能将lambda表达式推断为:

new Supplier<Long>() {
    @Override
    public Long get() {
        throw new RuntimeException();
    }
};
Run Code Online (Sandbox Code Playgroud)

这是在specs/docs中的某处记录的吗?这是仅在JDK> 8中添加的吗?

java lambda throw java-8 functional-interface

17
推荐指数
2
解决办法
553
查看次数

为什么@FunctionalInterface不能在JDK中符合条件的所有接口上使用?

Java 8为我们提供了许多有趣的方法来使用功能接口,并为它们添加了一个新的注释:@FunctionalInterface.如果我们不遵守功能接口的规则(只需要一个需要覆盖的抽象方法),它的工作就是告诉编译器对我们大喊大叫.

java.util.function包中43个接口,带有此批注.搜索jdk.1.8.0/src @FunctionalInterface只能获得57次点击.为什么其他可能添加的接口(如AutoCloseable)@FunctionalInterface仍然缺少它?

注释文档中有一些模糊的提示:

"用于指示接口类型声明旨在成为功能接口的信息性注释类型"

有没有什么好的理由不打算我设计的接口(可能只是一个功能接口)不能用作一个接口?除了没有意识到它可能被添加之外,是否有任何迹象?

是不是将抽象方法添加到任何已发布的接口来阻止实现它的任何人,功能与否?我觉得玩世不恭,假设他们只是懒得去追捕他们,但其他解释是什么?

更新:看过"应该'可比'是一个'功能界面'?" 我发现我仍然有唠叨的问题.当单一方法接口和功能接口在结构上相同时,它们会有什么不同?简单的名称是不同的?Comparable和Comparator在语义上足够接近.事实证明它们在结构上是不同的,但仍然不是最好的例子......

是否有一种情况,SMI在结构上很好用作功能接口,但仍然不鼓励接口名称和方法的语义含义?或者也许是Javadocs隐含的合同?

java functional-programming java-8 functional-interface

16
推荐指数
1
解决办法
2574
查看次数

什么时候应该在Java 8中使用Supplier?

这段代码有什么区别?

Supplier<LocalDate> s1 = LocalDate::now;
LocalDate s2 = LocalDate.now();

System.out.println(s1.get()); //2016-10-25
System.out.println(s2); //2016-10-25
Run Code Online (Sandbox Code Playgroud)

我开始学习Java 8中的功能接口,而不了解供应商的好处.究竟何时以及如何使用它们.供应商是否提高了绩效或者提取抽象水平的好处?

谢谢你的回答!这不是重复的问题,因为我使用搜索并没有找到我需要的东西.

更新1: 你的意思是这个?

    Supplier<Long> s1 = System::currentTimeMillis;
    Long s2 = System.currentTimeMillis();

    System.out.println(s1.get()); //1477411877817
    System.out.println(s2); //1477411877817
    try {
        Thread.sleep(3000l);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(s1.get()); //1477411880817 - different
    System.out.println(s2); //1477411877817
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface

16
推荐指数
5
解决办法
8645
查看次数