在下面的代码中,它在使用类名传递方法引用变量时起作用,但是当使用用户对象传递引用变量时会出现错误.
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) 下面的代码包含对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:
我在intellij中有这个代码:
return collection.stream().anyMatch(annotation ->
method.isAnnotationPresent(annotation));
Run Code Online (Sandbox Code Playgroud)
并且编译器告诉我"method.isAnnotationPresent(annotation)"可以用方法引用替换,我无法弄清楚如何做,因为它有一个参数.
有谁知道怎么做?
假设我们有一个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呼叫,使其更具可读性/紧凑性/清晰度?
我正在尝试重构以下代码:
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) 假设我有不同类型的吸气剂和固定剂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.而且我想将它用于不同的类型,不仅是字符串,还有整数等...
是否可以通过一些简单的方法解决而无需创建特殊转换器并将其与每个条目相关联?
我无法理解语法的方法参考,那里有两个参数a与b和参考是的方法a上b.
例如我明白了
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有三个或更多参数怎么办?这合法吗?第一个参数是否成为方法目标,剩下的参数是否成为参数?
我正在阅读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) 考虑以下简化的测试用例:
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方法引用看作是一个语法糖,它是作为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) method-reference ×10
java ×9
java-8 ×9
lambda ×5
generics ×2
closures ×1
ecj ×1
java-stream ×1
javac ×1
jls ×1
raw-types ×1
reflection ×1