标签: functional-interface

Java 8 - 功能接口与抽象类

我正在探索Java 8的功能,并遇到了"功能接口".

根据我的理解,这些接口可以有一些默认的实现方法:

@FunctionalInterface
public interface ComplexFunctionalInterface extends SimpleFuncInterface 
{
    default public void doSomeWork()
    {
        System.out.println("Doing some work in interface impl...");
    }
    default public void doSomeOtherWork()
    {
        System.out.println("Doing some other work in interface impl...");
    }
}
Run Code Online (Sandbox Code Playgroud)

但我怀疑的是,这是抽象类的用途.

为什么要介绍的功能接口.

java functional-interface

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

为什么Java 8的ToIntFunction <T>不扩展Function <T,Integer>

如果我编写了ToIntFunction接口,我想在接口中编码它只是一个返回原始int的函数,如下所示:

@FunctionalInterface
public interface ToIntFunction<T> extends Function<T, Integer> {
    int applyAsInt(T value);

    @Override
    default Integer apply(T value) {
        return Integer.valueOf(applyAsInt(value));
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道,有没有令人信服的理由让Java 8 API设计人员选择将原始备选方案与Function完全分开?是否有一些证据表明他们认为这样做并决定反对呢?我想类似的问题至少包括其他一些"特殊"功能接口,如Consumer(可能是Function <T,Void>)和Supplier(Function <Void,T>).

我没有深入和彻底地考虑过这个问题的所有后果,所以我可能会遗漏一些东西.

如果ToIntFunction(和其他原始泛型函数接口)与Function有这种关系,它将允许一个人在预期使用Function参数的位置使用它(想到的是与其他函数的组合,例如调用myFunction.compose(myIntFunction))或者当在如上所述的这种自动(非)装箱实现就足够时避免在API中编写几个专用函数.

这与这个问题非常相似:为什么Java 8的Predicate <T>不扩展Function <T,Boolean>但我已经意识到答案可能因语义原因而不同.因此,我正在重新设计这个函数的简单原始替代方案的问题,其中不存在任何语义,只是原始与包装类型,甚至消除了空包装对象的可能性.

java java-api java-8 functional-interface

6
推荐指数
2
解决办法
725
查看次数

创建函数流的更好方法是什么?

我希望对我定义的函数列表进行惰性评估,如下所示;

Optional<Output> output = Stream.<Function<Input, Optional<Output>>> of(
                    classA::eval, classB::eval, classC::eval)
            .map(f -> f.apply(input))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .findFirst();
Run Code Online (Sandbox Code Playgroud)

如您所见,每个类(a,b和c)都Optional<Output> eval(Input in)定义了一个方法.如果我尝试做

Stream.of(...)....
Run Code Online (Sandbox Code Playgroud)

它忽略了显式类型

T不是功能界面

编译错误.不接受T泛型类型的功能接口类型.of(T... values)


有没有更快捷的方法来创建这些功能的流?我讨厌明确定义of方法Function及其输入输出类型.它不会以更通用的方式工作吗?

这个问题源于以下问题的主题;
Lambda表达式和通用方法

java java-8 java-stream functional-interface

6
推荐指数
1
解决办法
650
查看次数

在Java8中组合两个函数

isReadyToDeliver方法中,如果订单中的所有产品都可用(ProductState.AVAILABLE)并且订单状态已准备好发送(OrderState.READY_TO_SEND),则方法必须返回true.我写了两部分,但我无法将它们组合在一起,

我写了,return orderState.andThen(productState)但得到这个错误:

andThen(Function<? super Boolean,? extends V>)类型中的方法Function<Order,Boolean>不适用于参数(Function<Order,Boolean>)

public class OrderFunctions  {

    public Function<Order, Boolean> isReadyToDeliver() {            
        Function<Order, Boolean> orderState = o -> o.getState() == OrderState.READY_TO_SEND;            
        Function<Order, Boolean>  productState = 
                o -> o.getProducts()
                    .stream()
                    .map(Product -> Product.getState())
                    .allMatch(Product -> Product == ProductState.AVAILABLE);

        return ????? ; 
       //return  orderState.andThen(productState);
       //error: The method andThen(Function<? super Boolean,? extends V>) in the type Function<Order,Boolean> is not applicable for the arguments (Function<Order,Boolean>) …
Run Code Online (Sandbox Code Playgroud)

java lambda functional-programming java-8 functional-interface

6
推荐指数
1
解决办法
442
查看次数

在Java中使用完整构造函数调用作为lambda表达式的方法引用

我很久以前就遇到过一个比我更好的竞争性答案,它使用了一个非常新的方法参考我作为lambda的替代品.

Stream.generate(new AtomicInteger(1)::getAndIncrement)...
Run Code Online (Sandbox Code Playgroud)

我查看了有关Method引用的Oracle规范,并定义了4种类型:

  • 参考静态方法 ContainingClass::staticMethodName
  • 引用特定对象的实例方法 containingObject::instanceMethodName
  • 引用特定类型的任意对象的实例方法 ContainingType::methodName
  • 引用构造函数 ClassName::new

我很难对这个进行分类.我没有在SO上发现任何问题或在文档中解释任何相关的问题.怎么会被翻译成匿名课程?

我的怀疑是:

IntStream.generate(new IntSupplier() {

    AtomicInteger atom = new AtomicInteger(1);

    @Override
    public int getAsInt() {
        return atom.getAndIncrement();
    }
})....
Run Code Online (Sandbox Code Playgroud)

......我不明白这是怎么回事.乍一看,我猜是表达式是:

IntStream.generate(new IntSupplier() {

    @Override
    public int getAsInt() {
        return new AtomicInteger(1).getAndIncrement();
    }
})....
Run Code Online (Sandbox Code Playgroud)

......但这不过是() -> new AtomicInteger(1).getAndIncrement().

这种表达式在哪里定义,以及如何在lambda/anonymous类中重写?

java lambda java-8 functional-interface

6
推荐指数
1
解决办法
192
查看次数

它的工作原理:BigDecimal Sum with Reduce和BigDecimal :: add

我可以理解为什么计算Total1,但是当计算Total2时我不知道!如何在BiFunction中使用BigDecimal :: add?签名不一样!!!

package br.com.jorge.java8.streams.bigdecimal;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class BigDecimalSumTest {
    public static void main(String[] args) {

        List<BigDecimal> list = new ArrayList<>();

        list.add(new BigDecimal("1"));
        list.add(new BigDecimal("2"));

        BigDecimal total1 = list.stream().reduce(BigDecimal.ZERO, (t, v) -> t.add(v));

        BigDecimal total2 = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

        System.out.println("Total 1: " + total1);
        System.out.println("Total 2: " + total2);
    }
}
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream functional-interface

6
推荐指数
1
解决办法
289
查看次数

使用 MethodHandleProxies 的正确方法

在我当前正在处理的一个 Java 项目中,我动态加载类,然后使用反射 API 来查找并执行那些具有某些注释的类的方法。

执行实际执行的代码专门根据 Java-8 功能接口工作(出于兼容性原因),因此我需要一个中间阶段,将Method使用反射发现的实例转换为适当的功能接口。我使用MethodHandleProxies类来实现这一点。

再次出于兼容性原因,所讨论的功能接口是通用接口。这会在使用该方法时导致“未经检查的转换”警告MethodHandleProxies.asInterfaceInstance,因为该方法返回“裸”接口。

以下是一个简短的示例,重现了所涉及的主要步骤:

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TestClass {
    private String prefix;

    public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, SecurityException {
        // Use reflection to find method.
        Method method = Arrays.stream(TestClass.class.getDeclaredMethods()) // Stream over methods of ConsumerClass
                .filter(m -> m.isAnnotationPresent(Marker.class)) // Retain only methods with @Marker annotation
                .findFirst().get(); // Get first such method …
Run Code Online (Sandbox Code Playgroud)

java reflection java-8 functional-interface

5
推荐指数
1
解决办法
457
查看次数

为什么两个方法引用被编译到两个不同的地址?

我两次引用相同的方法,但引用不同。看这个例子:

import java.util.function.Consumer;

public class MethodRefTest {
    public static void main(String[] args) {
        new MethodRefTest();
    }

    public MethodRefTest() {
        Consumer<Integer> a = this::method;
        System.out.println(a);
        Consumer<Integer> b = this::method;
        System.out.println(b);
    }

    public void method(Integer value) {

    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

MethodRefTest$$Lambda$1/250421012@4c873330
MethodRefTest$$Lambda$2/295530567@776ec8df
Run Code Online (Sandbox Code Playgroud)

方法引用只不过是匿名类的语法糖吗?如果不是,我该怎么做才能始终获得相同的方法引用?(除了在字段中存储一次参考以供使用之外。)

(应用:我认为方法引用是观察者实现的一种更漂亮的方式。但是每次使用不同的引用,一旦添加观察者就不可能从可观察者中删除观察者。)

java functional-interface method-reference

5
推荐指数
1
解决办法
386
查看次数

在 lambda 函数中获取接口引用

考虑以下代码:

val hwnd = Handler()
hwnd.postDelayed(object : Runnable {
        override fun run()
            hwnd.postDelayed(this, 5000)
        }
}, 5000)
Run Code Online (Sandbox Code Playgroud)

这样,我可以通过thisrun()方法中使用(指的是 Runnable)将相同的 Runnable 发布到 Handler 。但是我怎么能只使用一个 lambda 表达式来做同样的事情呢?

val hwnd = Handler()
hwnd.postDelayed({
    //How to get "this" here?
}, 5000)
Run Code Online (Sandbox Code Playgroud)

这甚至可能吗?

java lambda android kotlin functional-interface

5
推荐指数
1
解决办法
311
查看次数

Java 函数式接口和 Lambda 表达式

鉴于以下代码,有人可以解释为什么断言返回 true 吗?尽管已经进行了无数次搜索,但我无法得到任何适当的答案,说明为什么会出现这种情况,Java 特性是什么导致了这种行为,以及我在类似地创建这样的接口时会遇到哪些限制/要求作为这个。

interface X {
  default int foo() {return 1;}
  String bar();
}

public class Exercise{
  public static void main(String[]arg){
    X foo1=()->"hello";
    assert (foo1.bar()).equals("hello");
  }
}
Run Code Online (Sandbox Code Playgroud)

java lambda functional-interface

5
推荐指数
1
解决办法
246
查看次数