标签: functional-interface

将Comparable的实例传递给期望Comparator的方法

StreamJava 8中的类定义了一个max需要Comparator参数的方法.这是方法签名:

Optional<T> max(Comparator<? super T> comparator)
Run Code Online (Sandbox Code Playgroud)

Comparator是一个compare具有此签名的抽象方法的功能接口.通知compare需要2个参数.

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

Comparable接口具有compareTo带此签名的抽象方法.通知compareTo只需要1个参数.

int compareTo(T o)
Run Code Online (Sandbox Code Playgroud)

在Java 8中,以下代码完美地运行.但是,我期望编译错误,例如"Integer类没有定义compareTo(Integer,Integer)".

int max = Stream.of(0, 4, 1, 5).max(Integer::compareTo).get();
Run Code Online (Sandbox Code Playgroud)

有人可以帮助解释为什么即使他们的方法签名不兼容Comparable,Comparator也可以将实例传递给期望实例的方法?

java comparable comparator java-8 functional-interface

11
推荐指数
1
解决办法
3567
查看次数

如何在Java函数中适当地组合谓词和函数?

目的是创建一个可在流过滤器中使用的新谓词:

myCollectionOfElement
.stream()
.filter(
    MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1()))
.sorted(MyStaticHelperClass.getOtherSubElement().reversed())
.limit(10)
.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)

getSubElement1OfTheElement()返回Function<E,S>(E包含S属性) getPredicate1OnSubElement1()返回Predicate<S>

我使用静态函数来公开方法引用和函数.我这样做是因为在Velocity模板中调用了流,并且此上下文不支持lambda语法和方法引用. 我不想为所有可能的组合创建静态函数,所以我真的希望它们是可组合的.

例如,在这里,我不想有静态,getPredicate1OnElementThatCheckProperty1OnTheSubElement1()因为我可以撰写getSubElement1OfTheElement()getPredicate1OnSubElement1().

所以我需要一个撰写函数:

// returns a new Predicate constructed by applying Predicate predicate on the result of Function function
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<S> predicate)

// most intuitive : lambda
return value -> predicate.test(function.apply(value));

// with method references
return function.andThen(predicate::test)::apply;
// predicate.compose is not available because Predicate interface doesn't extends Function …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 functional-interface method-reference

11
推荐指数
1
解决办法
2611
查看次数

从java8迁移到java9时,对方法的引用是不明确的

我正在将项目从JAVA 8迁移到JAVA 9,我在使代码工作时遇到了一些麻烦.所有工作在JAVA 8但在9我有以下错误:

Error java: reference to ok is ambiguous
      both method <T>ok(java.util.function.Supplier<T>)  and method ok(web.Procedure) match
Run Code Online (Sandbox Code Playgroud)

这是我调用方法时的代码:

public ResponseEntity<List<MailTemplateDto>> mailTemplateFindAll() {
    return ok(() -> mailTemplateService.findAll());
}
Run Code Online (Sandbox Code Playgroud)

这是实施:

 public <T> ResponseEntity<T> ok(Supplier<T> action) {
     return this.body(HttpStatus.OK, action);
 }

 public <T> ResponseEntity<T> ok(T body) {
     return this.ok(() -> {
         return body;
     });
 }

 public ResponseEntity<Void> ok(Procedure action) {
     action.invoke();
     return this.status(HttpStatus.OK);
 }

 public ResponseEntity<Void> ok() {
     return this.status(HttpStatus.OK);
 }
Run Code Online (Sandbox Code Playgroud)

Procedure接口的代码:

@FunctionalInterface
public interface Procedure {
    void invoke();
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?


可重现的代码 …

java compiler-errors java-8 functional-interface java-9

11
推荐指数
1
解决办法
406
查看次数

Java方法不能与Lambda表达式一起应用

我已经观看并阅读了https://caveofprogramming.com/java/whats-new-in-java-8-lambda-expressions.html并且我遵循了我为跑步者对象所做的相同模式.

Runner runner = new Runner();
runner.run(() -> System.out.println("Print from Lambda expression"));
Run Code Online (Sandbox Code Playgroud)

然后,我尝试创建一个简单的接口和类来应用我学到的东西.我只想用lambda表达式替换匿名类.我的理解是lambda表达式是匿名类的较短代码并提高了可读性.

所以,我试图启动另一个实例调用eucalyptus1并尝试@Overridegrow()方法,但我的IDE错误消息说:

grow()com.smith.Eucalyptus无法应用(lambda expression)

有人能指出我在这里误解了什么吗?

代码如下:

// a simple interface
interface Plant {
    public void grow();
}

// apply interface to class
class Eucalyptus implements Plant {
    @Override
    public void grow() {
        System.out.println("This is from Eucalyptus");
    }
}

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

        // Create an instance of Eucalyptus
        Eucalyptus eucalyptus …
Run Code Online (Sandbox Code Playgroud)

java lambda overriding java-8 functional-interface

11
推荐指数
3
解决办法
2128
查看次数

意外的Java功能接口转换

我有以下代码,它使用编译的java Functional Interfaces,但不清楚它为什么要编译:

public class App {

    public static void main(String[] args) throws Exception {

        final RecordIterator it = new RecordIterator<MyRecord>();

        final UpdateManager updateManager = new UpdateManager();
        updateManager.doUpdateForEach(it, DatabaseOperator::updateInfo);

    }
}

class UpdateManager {

    public void doUpdateForEach(final RecordIterator recordIterator,
                                final FunctionalStuff<MyRecord> updateAction) throws Exception {

        updateAction.execute(new DatabaseOperator(), new MyRecord());

    }

}

class RecordIterator<E> {

}

@FunctionalInterface
interface FunctionalStuff<T> {

    void execute(final DatabaseOperator database, final T iterator) throws Exception;

}

class DatabaseOperator {

    public void updateInfo(final MyRecord r) {

    }

} …
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface

11
推荐指数
1
解决办法
209
查看次数

如何在Java 8编译时确保方法签名"实现"功能接口

Java 8中是否存在implements方法关键字的任何模拟?

假设我有一个功能界面:

@FunctionalInterface
interface LongHasher {
    int hash(long x);
}
Run Code Online (Sandbox Code Playgroud)

一个包含3个静态方法的库"实现"这个功能接口:

class LongHashes {
    static int xorHash(long x) {
        return (int)(x ^ (x >>> 32));
    }
    static int continuingHash(long x) {
        return (int)(x + (x >>> 32));
    }
    static int randomHash(long x) {
         return xorHash(x * 0x5DEECE66DL + 0xBL);
    }
}
Run Code Online (Sandbox Code Playgroud)

在将来,我希望能够互换地使用对这3种方法的任何引用作为参数.例如:

static LongHashMap createHashMap(LongHasher hasher) { ... }
...
public static void main(String[] args) {
    LongHashMap map = createHashMap(LongHashes::randomHash);
    ...
}
Run Code Online (Sandbox Code Playgroud)

我如何能确保在编译时间LongHashes::xorHash, …

java java-8 functional-interface

10
推荐指数
2
解决办法
1044
查看次数

方法引用似乎并不总是捕获实例

我知道关于这个问题有很多问题,即使是最近的问题,但我仍然无法解决一件事。考虑以下功能接口

@FunctionalInterface
interface PersonInterface {
    String getName();
}
Run Code Online (Sandbox Code Playgroud)

而这个实现:

class Person implements PersonInterface {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果查看这些线程12,我希望输出以下代码"Bob",而不抛出a,NullPointerException因为据我了解,在创建我的Supplier时,它捕获了Person实例。

Person p = new Person("Bob");
Supplier<String> f = p::getName;
p = null;
System.out.println(f.get());
Run Code Online (Sandbox Code Playgroud)

并正确输出 "Bob"

现在我不明白的是为什么下面的代码也没有输出"Bob"

Person p = new Person("Bob"); …
Run Code Online (Sandbox Code Playgroud)

java instance java-8 functional-interface supplier

10
推荐指数
2
解决办法
102
查看次数

Java 8流,为什么要编译第2部分......或者什么是方法参考,真的吗?

好的,这个"系列"中的第一个问题就是这个问题.

现在,这是另一个案例:

Arrays.asList("hello", "world").stream().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

这编译,并工作......

好的,在上一个问题中,使用了中的静态方法.

但现在这是不同的:System.out是一个static领域System,是的; 它也是一个PrintStream,并且PrintStream有一个println()恰好匹配a的签名的方法Consumer,并且a ConsumerforEach()期望的.

所以我试过这个......

public final class Main
{
    public static void main(final String... args)
    {
        Arrays.asList(23, 2389, 19).stream().forEach(new Main()::meh);
    }

    // Matches the signature of a Consumer<? super Integer>...
    public void meh(final Integer ignored)
    {
        System.out.println("meh");
    }
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理!

这是一个完全不同的范围,因为我启动了一个新实例,并且可以在构造此实例后立即使用方法引用!

那么,一个方法参考真的是任何服从签名的方法吗?有什么限制?有没有人可以建立一个"@FunctionalInterface兼容"的方法,不能用于@FunctionalInterface

java java-8 functional-interface

9
推荐指数
1
解决办法
489
查看次数

为什么在 Java 8 中使用 @FunctionalInterface 注解

如果我们的接口中只有一个抽象方法,那么默认情况下它是函数式接口。任何人都可以解释@FunctionalInterface 注释带来的额外优势吗?

我知道如果我们添加@FunctionalAnnotation,它不会允许有人在接口中添加另一个抽象方法,因为它会给出编译错误,但我的意思是即使你不使用@FucntionalInterface注解,那么还有,如果有人会添加另一个抽象方法,它会破坏代码中所有现有的 lambda 表达式,编译器会抱怨。

例如:

如果我有以下界面:

public interface User {

    Integer fetchData(Integer userId);
}
Run Code Online (Sandbox Code Playgroud)

具有以下实现:

public class UserImpl implements User{

    @Override
    public Integer fetchData(Integer userId) {
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

和以下用法:

公共类 TestFunctionalInterface {

public static void main(String[] args) {
    User user = a -> a*2;
    System.out.println("FetchedData:"+user.fetchData(2));
}
Run Code Online (Sandbox Code Playgroud)

}

现在,如果我尝试在界面中添加另一个方法,如下所示:

public interface User {

    Integer fetchData(Integer userId);

    Integer fetchLoginDetails(Integer userId);

}
Run Code Online (Sandbox Code Playgroud)

编译器在下面的代码中抱怨:

public class TestFunctionalInterface {

    public static void main(String[] args) {
        User user = a -> a*2;
        System.out.println("FetchedData:"+user.fetchData(2)); …
Run Code Online (Sandbox Code Playgroud)

java-8 functional-interface

9
推荐指数
3
解决办法
5227
查看次数

使用Set <String>和String作为参数创建自定义谓词

我有一个String"ishant"和一个Set<String>["Ishant","Gaurav","sdnj"].我需要为此编写谓词.我尝试过如下代码,但它无法正常工作

Predicate<Set<String>,String> checkIfCurrencyPresent = (currencyList,currency) -> currencyList.contains(currency);
Run Code Online (Sandbox Code Playgroud)

如何创建一个Predicate将采取Set<String>String作为参数,并可以给结果呢?

java predicate java-8 functional-interface

9
推荐指数
2
解决办法
209
查看次数