标签: method-reference

引用特定对象的实例方法

在下面的代码中,它在使用类名传递方法引用变量时起作用,但是当使用用户对象传递引用变量时会出现错误.

public class User {
    private String name;

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

    public void printName() {
        System.out.println(name);
    }    
}


public class Main {
    public static void main(String[] args) {
        User u1 = new User("AAA");
        User u2 = new User("BBB");
        User u3 = new User("ZZZ");

        List<User> userList = Arrays.asList(u1, u2, u3);        

        userList.forEach(User::printName); // works
        userList.forEach(u1::printName); // compile error
    }
}
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 method-reference

8
推荐指数
1
解决办法
1719
查看次数

方法引用原始类型有害吗?

下面的代码包含对Enum::name(通知无类型参数)的引用.

public static <T extends Enum<T>> ColumnType<T, String> enumColumn(Class<T> klazz) {
    return simpleColumn((row, label) -> valueOf(klazz, row.getString(label)), Enum::name);
}

public static <T, R> ColumnType<T, R> simpleColumn(BiFunction<JsonObject, String, T> readFromJson,
        Function<T, R> writeToDb) {
 // ...
}
Run Code Online (Sandbox Code Playgroud)

Javac在编译期间报告警告:

[WARNING]发现原始类型:java.lang.Enum缺少泛型类java.lang.Enum的类型参数

更改表达式会Enum<T>::name导致警告消失.

但是,Idea会在Enum<T>::name版本上标记以下警告:

可以推断出显式类型参数

反过来,Eclipse(ECJ)没有报告任何一种配方的任何问题.

这三种方法中哪一种是正确的?

一方面原始类型相当令人讨厌.如果你试图放一些其他的类型参数,例如 Enum<Clause>::name会导致编译失败,所以这是一些额外的保护.

另一方面,上面的引用等同于e -> e.name()lambda,这个公式不需要类型参数.

Enviorment:

  • Java 8u91
  • IDEA 15.0.3社区
  • ECJ 4.5.2

javac raw-types java-8 method-reference ecj

8
推荐指数
1
解决办法
480
查看次数

可以使用java中的反射替换方法引用

我在intellij中有这个代码:

 return collection.stream().anyMatch(annotation -> 
                        method.isAnnotationPresent(annotation));
Run Code Online (Sandbox Code Playgroud)

并且编译器告诉我"method.isAnnotationPresent(annotation)"可以用方法引用替换,我无法弄清楚如何做,因为它有一个参数.

有谁知道怎么做?

java reflection intellij-idea java-8 method-reference

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

在数组映射期间将lambda替换为flatMap中的方法引用

假设我们有一个Customer班级:

public class Customer {
    private Car[] cars;
    // getter, setter, constructor
}
Run Code Online (Sandbox Code Playgroud)

和我们需要在汽车上映射的客户的集合.

目前我正在以某种方式这样做:

Collection<Customer> customers = ...
customers.stream().flatMap(
        customer -> Arrays.stream(customer.getCars())
)...
Run Code Online (Sandbox Code Playgroud)

它运行良好,但代码看起来不优雅.我真的想用使用方法引用的代码替换它,这些代码通常看起来更易读,更紧凑.但是使用数组类型的字段会很难.

问题:有没有任何方法可以增强flatMap呼叫,使其更具可读性/紧凑性/清晰度?

java lambda functional-programming java-8 method-reference

8
推荐指数
2
解决办法
1443
查看次数

创建非捕获方法引用,它将调用超类方法

我正在尝试重构以下代码:

class Base {
  private Object a, b, <...>; // there's like 10 of these attributes of different type

  public Object a() {
    return a;
  }
  public Object b() {
    return b;
  }
  // more getters like the ones above
}

class RootNode extends Base { }

class BranchNode extends Base {
  private RootNode root; // passed via constructor

  public Object a() {
    Object value = super.a();
    return value != null ? value : root.a();
  }
  public Object b() { …
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference

8
推荐指数
1
解决办法
146
查看次数

通过getter和setter更新pojos的通用方法

假设我有不同类型的吸气剂和固定剂POJO.我想写一些通用算法,只需通过lambdas定义getter和setter,就可以将数据从一个更新到另一个.我试图以这种方式创建它

private static final Map<Function<Entity, Object>, BiConsumer<Entity, Object>> ACCESSORS = new HashMap
        <Function<Entity, Object>, BiConsumer<Entity, Object>>() {{
    put(Entity::getAreaCode, Entity::setAreaCode);
}});
Run Code Online (Sandbox Code Playgroud)

然后我遍历所有应用目标实体的条目,如果getter的结果不为null,那么我想为其他实体应用相应的setter.

但它不起作用,因为Object不能转换为String.而且我想将它用于不同的类型,不仅是字符串,还有整数等...

是否可以通过一些简单的方法解决而无需创建特殊转换器并将其与每个条目相关联?

java generics lambda java-8 method-reference

8
推荐指数
1
解决办法
283
查看次数

实例方法参考和Lambda参数

我无法理解语法的方法参考,那里有两个参数ab和参考是的方法ab.

例如我明白了

Arrays.sort(personArray, comparators::compareByName);
Run Code Online (Sandbox Code Playgroud)

相当于

Arrays.sort(personArray, (o1, o2) -> comparators.compareByName(o1, o2));
Run Code Online (Sandbox Code Playgroud)

因为在这种情况下,lambda参数与方法调用参数匹配(o1, o2).

这个lambda的情况如何

stream.sorted((o1, o2) -> o1.compareToIgnoreCase(o2));
Run Code Online (Sandbox Code Playgroud)

我的IDE告诉我这相当于:

stream.sorted(String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)

我没有找到替换该语法的规则:a.method(b)使用方法引用.

例如,如果lambda有三个或更多参数怎么办?这合法吗?第一个参数是否成为方法目标,剩下的参数是否成为参数?

java lambda closures java-8 method-reference

7
推荐指数
1
解决办法
550
查看次数

Java 8构造函数方法引用

我正在阅读perform message它附带的样本我重现..

@FunctionalInterface
public interface Action {
    public void perform();
}
Run Code Online (Sandbox Code Playgroud)

实施者

public final class ActionImpl implements Action {
    public ActionImpl() {
        System.out.println("constructor[ActionIMPL]");
    }

    @Override
    public void perform() {
        System.out.println("perform method is called..");
    }    
}
Run Code Online (Sandbox Code Playgroud)

来电者.

public final class MethodReferences {

    private final Action action;

    public MethodReferences(Action action) {
        this.action = action;
    }

    public void execute() {
        System.out.println("execute->called");
        action.perform();
        System.out.println("execute->exist");
    }

    public static void main(String[] args) {
        MethodReferences clazz = new MethodReferences(new ActionImpl());
        clazz.execute();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果调用此方法则将以下内容打印到输出中

constructor[ActionIMPL] …
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference constructor-reference

7
推荐指数
1
解决办法
5372
查看次数

对于一元静态方法的方法引用在Function和BiFunction参数类型之间是不明确的

考虑以下简化的测试用例:

import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
public final class Example {
    static class PairList<A, B> {
        public void replaceAllSecond(Function<? super B, ? extends B> secondFunction) {}
        public void replaceAllSecond(BiFunction<? super A, ? super B, ? extends B> secondFunction) {}
    }

    static class ImmutableList<E> extends AbstractList<E> {
        public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {return null;}
        public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {return null;}
        public static <E> ImmutableList<E> copyOf(Iterator<? extends E> …
Run Code Online (Sandbox Code Playgroud)

java jls java-8 method-reference

7
推荐指数
1
解决办法
165
查看次数

为什么方法引用会产生java.lang.BootstrapMethodError

我曾经把java方法引用看作是一个语法糖,它是作为lambda表达式的一个补充而引入的.但显然事实并非如此.

在下面的示例中,与lambda表达式不同,方法引用会产生错误.
有人可以解释一下奇怪的行为吗?

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {

    public static void main(String[] args) {
        System.out.println(getMapUsingLanmdaApproach(MyEnum.class)); // works as expected: {1=A, 2=B}
        System.out.println(getMapUsingMethodReferenceApproach(MyEnum.class));   // throws java.lang.BootstrapMethodError
    }

    static <K, V extends Enum<?> & HasProperty<K>> Map<K, V> getMapUsingLanmdaApproach(Class<V> aClass) {
        return Stream.of(aClass.getEnumConstants())
                .collect(Collectors.toMap(e -> e.getProperty(), Function.identity()));
    }

    static <K, V extends Enum<?> & HasProperty<K>> Map<K, V> getMapUsingMethodReferenceApproach(Class<V> aClass) {
        return Stream.of(aClass.getEnumConstants())
                .collect(Collectors.toMap(HasProperty::getProperty, Function.identity()));
    }
}

enum MyEnum implements HasProperty<Integer> {
    A(1),
    B(2);

    private final Integer …
Run Code Online (Sandbox Code Playgroud)

java generics lambda java-stream method-reference

7
推荐指数
0
解决办法
104
查看次数