标签: functional-interface

在Java 8中使用Lambda进行异常处理

我正在使用lambda表达式进行一些测试,但我的代码不能编译.我的lambda实现是错误的还是异常处理?以下代码的正确实现是什么?

class MyObject { }

interface Creatable<T> {
    T create() throws IOException;
}

/* Using the code: */
Creatable<MyObject> creator = () ->  {
    try {
        return new MyObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
};

MyObject obj1 = creator.create();
Run Code Online (Sandbox Code Playgroud)

如果我删除try catch块并声明抛出该方法的异常,代码将编译并正常运行.

Creatable<MyObject> creator = () -> new MyObject();
Run Code Online (Sandbox Code Playgroud)

编译错误是:

incompatible types: bad return type in lambda expression

java lambda java-8 functional-interface

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

Java 8中的功能接口(方法执行时间记录器)

我有两种方法:

class C1
{

  void m1() {//does sth}

  void m2(int x1, int x2) {//does sth}

 }
Run Code Online (Sandbox Code Playgroud)

//记录任何方法所用的时间

 logMethodExecTime(m1);
 logMethodExecTime(m2);
Run Code Online (Sandbox Code Playgroud)

不知道如何使用JDK8功能接口和方法引用来定义方法'logMethodExecTime'的正确语法?

以下不起作用:

class Utils
{
   public static void logMethodExecTime(Supplier<Void> s)
   {
     long start = System.nanoTime();
     s.get();
     long end = System.nanoTime();
     System.out.println(((end-start)/1000000000d) + " secs");
   }
 }
Run Code Online (Sandbox Code Playgroud)

和调用:

      C1 c = new C1();  
      Utils.logMethodExecTime(c::m1);

//Also how can we have one single definition of 'logMethodExecTime' 
//to accept any method with any number of args    
      Utils.logMethodExecTime(c::m2);
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface

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

Java 8 功能接口(Consumer)附加参数

是否有可能以某种方式参数化 Java 8 Consumer?我想要有可重用的消费者,我可以在其中放置额外的参数。

List<DateTime> dates = new ArrayList<DateTime>();
Set<Alarm> alarms = new HashSet<Alarm>();

Consumer<Entry> entryConsumer1 = entry -> {
    LocalTime time = entry.getDate().toLocalTime();
    Alarm alarm = new Alarm(time, calendar1.getPattern());
    alarms.add(alarm);
    dates.add(entry.getDate());
};

Consumer<Entry> entryConsumer2 = entry -> {
    LocalTime time = entry.getDate().toLocalTime();
    Alarm alarm = new Alarm(time, calendar2.getPattern());
    alarms.add(alarm);
    dates.add(entry.getDate());
};

calendar1.generateEntries(criteria).forEach(entryConsumer1);
calendar2.generateEntries(criteria).forEach(entryConsumer2);
Run Code Online (Sandbox Code Playgroud)

calendar1, calendar2 是同一种类型

如您所见,两个消费者仅在一个论点上有所不同。是否可以简化此代码/不要重复?

java lambda java-8 functional-interface

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

Java - lambda推断类型

我正在玩a的用法FunctionalInterface.我到处都看到了以下代码的多种变体:

int i = str != null ? Integer.parseInt() : null;
Run Code Online (Sandbox Code Playgroud)

我正在寻找以下行为:

int i = Optional.of(str).ifPresent(Integer::parseInt);
Run Code Online (Sandbox Code Playgroud)

ifPresent只接受一个Supplier,Optional不能扩展.

我创建了以下内容FunctionalInterface:

@FunctionalInterface
interface Do<A, B> {

    default B ifNotNull(A a) {
        return Optional.of(a).isPresent() ? perform(a) : null;
    }

    B perform(A a);
}
Run Code Online (Sandbox Code Playgroud)

这允许我这样做:

Integer i = ((Do<String, Integer>) Integer::parseInt).ifNotNull(str);
Run Code Online (Sandbox Code Playgroud)

可以添加更多默认方法来执行诸如此类操作

LocalDateTime date = (Do<String, LocalDateTime> MyDateUtils::toDate).ifValidDate(dateStr);
Run Code Online (Sandbox Code Playgroud)

它读得很好Do [my function] and return [function return value] if [my condition] holds true for [my input], …

java lambda functional-interface

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

当我将lambda表达式作为参数传递它可以访问此范围内的其他变量时,怎么可能?

public class ArraysDemo {

    public static void main(String[] args) {

          int[] a = {0, 2, 4, 6, 8};
          int[] b = {10, 12, 14, 16, 18};
          Arrays.setAll(a, i -> b[i]+1);
          System.out.println(Arrays.toString(a));
    }  
}
Run Code Online (Sandbox Code Playgroud)

输出: [11, 13, 15, 17, 19]

setAll()使用的函数的来源如下:

public static void setAll(int[] array, IntUnaryOperator generator) {
        Objects.requireNonNull(generator);
        for (int i = 0; i < array.length; i++)
            array[i] = generator.applyAsInt(i);
}
Run Code Online (Sandbox Code Playgroud)

IntUnaryOperator 是一个功能界面,这是其来源的一部分:

public interface IntUnaryOperator {
    int applyAsInt(int operand);
    // rest methods are omitted
}
Run Code Online (Sandbox Code Playgroud)

如果我错了,请纠正我,但我对Java中lambda表达式的理解是,当我将lambda表达式作为参数传递给setAll() …

java arrays lambda interface functional-interface

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

如何将简单的setter解释为Consumer <T>?

首先,请耐心等待.大部分时间我在Scala(有时只在JVM端)或其他语言工作,所以我的Java(8)知识有点受限!

我必须重构的代码充满了空检查.我想让一些pojo的属性设置/覆盖更好一点,并且很高兴能够使用Java 8来完成工作.

所以我创造了这个:

private <T> void setOnlyIfNotNull(final T newValue, Consumer<T> setter) {
    if(newValue != null) {
        setter.accept(newValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

setOnlyIfNotNull(newUserName, user::setName);
Run Code Online (Sandbox Code Playgroud)

junit4-test看起来像这样:

@Test
public void userName_isOnlyUpdated_ifProvided() {
   User user = new User("oldUserName");

   UserUpdateRequest request = new UserUpdateRequest().withUserName("newUserName");   
service.updateUser(user, request); // This calls setOnlyIfNotNull behind the curtain. And it does invoke the setter ONLY once!

 assertThat(user.getUserName()).isEqualTo("newUserName");
}
Run Code Online (Sandbox Code Playgroud)

这很有效.在我请同事进行代码审查之前,我对自己很满意.在解释我做了什么之后,他详细说明了他认为这不起作用,因为函数仍然没有Java中的一等公民,而User-pojo没有扩展FunctionalInterface.接口也是在类级别而不是功能级别上提供的.

现在我想知道,为什么测试工作,我在这里滥用了什么?天真我只是想象Java编译器知道setter的T setT(T value)签名与a相同Consumer<T>.

编辑:详细说明一下:如果我将测试更改为失败,例如,assertThat(user.getUserName()).isEqualTo("Something");如果失败,则会按预期进行compareFailure!

java functional-programming java-8 functional-interface

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

目标类型的表达式必须是一个功能接口 - 为什么需要它?

我已经经历了许多具有相同标题的问题,但我没有得到我正在寻找的答案.

Greeter下面的课程中有一个简单的sysout.据我了解,lambda关心的是签名(即返回类型和参数数量).但如果我删除

int add(int a);

它完美有效,因为编译器将检查Greeting接口中是否有任何可用的方法没有参数且返回类型为void.

但是当我在那里保留那个方法时,我得到了主题行中提到的编译错误,根据我的理解编译器将转到Greeting接口,它将看到有两种方法.但是应该没有歧义,因为我的lambda表达式查找返回类型为void且只有一个参数的方法.基于这个类比,只有一种方法,所以理想情况下它不应该给出错误.

我知道我的比喻在这里是错误的,我知道它必须是一个功能界面,但我也认为我上面提到的过程正是编译器的工作方式.

任何人都可以让我知道我错在哪里以及编译器在我的例子中是如何工作的?

问候界面

package lambadas;

public interface Greeting {
    void perform();
    int add(int a);
}
Run Code Online (Sandbox Code Playgroud)

迎宾班

package lambadas;

public class Greeter {

    public static void main(String[] args) {
        Greeting l = () -> System.out.println("hello");
        l.perform();
    }
}
Run Code Online (Sandbox Code Playgroud)

HelloWorldGreeting

package lambadas;

public class HelloWorldGreeting implements Greeting {

    @Override
    public void perform() {
        System.out.println("hello world.!");
    }
    @Override
    public int add(int a) {
      return 0;
    }

}
Run Code Online (Sandbox Code Playgroud)

java lambda compiler-errors java-8 functional-interface

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

BinaryOpertor for List &lt;Integer&gt;添加列表

在前面的问题中,我曾问过我应该使用哪个FunctionalInterface?

现在,我尝试添加到List<Integer>而不是两个Integers ab,这样每个索引都添加到另一个列表的相同索引中。

我以前有

 BinaryOperator<Integer> binaryOperator = Integer::sum;
Run Code Online (Sandbox Code Playgroud)

用于使用加上两个整数binaryOperator.apply(int a,int b)。有没有类似的方式

BinaryOperator<List<Integer>> binaryOperator = List<Integer>::sum;
Run Code Online (Sandbox Code Playgroud)

然后得到结果List<Integer> cList

java java-8 java-stream functional-interface

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

如何在Java中为枚举值提供实现?

我有枚举类的值,假设它会随着时间的推移而增长,我希望添加新枚举值的用户也能在某处提供强制作用.但是我不确定如何强迫他们提供实施,因为在其他课程中会有必要.例如

public enum DayType {
    SUNDAY,
    MONDAY;
}
Run Code Online (Sandbox Code Playgroud)

在课堂上提到

class X{
DateType dateType;
..
}
Run Code Online (Sandbox Code Playgroud)

并用于其他一些课程

if (x.getDateType().equals(DayType.SUNDAY)) {
...
}else if(x.getDateType().equals(DayType.MONDAY)){
..
}
Run Code Online (Sandbox Code Playgroud)

因此,如果有人添加了DateType,那么他应该被迫在上面的if-else逻辑中添加必要条件.如果可能,最好通过添加功能接口?

我无法在枚举类中强制执行,因为必需具有spring依赖性.

java enums functional-interface

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

一个参数的BiConsumer和方法参考

为什么将一个参数的方法引用作为期望类型的参数(BiConsumer抽象方法需要两个参数)传递是合法的?

例:

class Experiment {

    private String name;

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

    public void oneParamMethod(Object o) {
        System.out.println(this.name + " and " + o);
    }

    public <T, S> void executeBiConsumer(BiConsumer<T, S> biCon, T in1, S in2) {
        biCon.accept(in1, in2);
    }

    public static void main(String[] args) {

        // notice that the name is "INSTANCE", but it won't be printed out
        Experiment exp = new Experiment("INSTANCE");

        // executeBiConsumer expects a functional of two params but is …
Run Code Online (Sandbox Code Playgroud)

java this java-8 functional-interface method-reference

3
推荐指数
2
解决办法
117
查看次数