如何将 Java 供应商绑定到 object 的实例?
How to bind a Java Supplier to an instance of an object?
如何将 Java Supplier
绑定到 Object 的现有实例?例如,如果我想用这个 header:
编写自己的 compareTo()
方法
public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
我希望可以这样称呼它:
myCompareTo("Hello", "Hello2", String::length);
其中 String
(大写字母)是 class 而不是 object。那么如何将实例 o1
绑定到供应商?
您可以使用
Comparator.comparing(String::length);
获取可传递给方法的比较器实例。
这是您要搜索的内容(我相信):
public static <T, U extends Comparable<U>> int compare(T o1, T o2, Function<T, U> mapper) {
return mapper.apply(o1).compareTo(mapper.apply(o2));
}
你可以这样称呼它:
compare("str1", "str2", String::length); // 0
感谢您的回答。其实我现在想通了。我想要提供的对象实例(o1 和 o2)来执行给定的方法。我发现 Supplier 是错误的接口,我不得不使用 Function。在这里你可以看到我的工作简化示例:
public static <T> int myCompareTo(T o1, T o2, Function<T, Comparable> getter) {
return getter.apply(o1).compareTo(getter.apply(o2));
}
接口必须是 Function 而不是 Supplier 的原因是,只有 Function 等同于接受对象并调用对象上引用的方法的 lambda 表达式。
例如,如果您将方法引用定义为:
Function<TypeOfInstance, ReturnTypeOfReferencedMethod> methodReference = TypeOfInstance::referencedMethod();
那么正在执行的等效 lambda 表达式是:
(instance) -> instance.referencedMethod()
附加信息:
编辑:我知道我可以通过使用 Comparator 来完成同样的操作,但是这个例子非常简单。在我的应用程序中,这种功能是必需的。我必须创建一个 compareTo 函数来按多个属性对 ArrayList 进行排序,因为主要排序属性在列表中可能不是唯一的。我想与您分享我的代码,因为我认为这对您来说可能是一个有趣的见解。
public static <T> int ultimateCompare(T o1, T o2, Function<T, Comparable>... getters) {
for (Function<T, Comparable> getter : getters) {
int result = getter.apply(o1).compareTo(getter.apply(o2));
if (result != 0) return result;
}
return 0;
}
以这个为例,你可以按照姓氏对一个人的列表进行排序,如果其中两个相同,你可以使用名字来排序。使用此解决方案,您可以在运行时更改排序。
实际上,更正确的定义方法的方法是:
private static <T, U extends Comparable<? super U>> int myCompareTo(T left, T right, Function<T, U> fu) {
return Comparator.comparing(fu).compare(left, right);
}
如何将 Java Supplier
绑定到 Object 的现有实例?例如,如果我想用这个 header:
compareTo()
方法
public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
我希望可以这样称呼它:
myCompareTo("Hello", "Hello2", String::length);
其中 String
(大写字母)是 class 而不是 object。那么如何将实例 o1
绑定到供应商?
您可以使用
Comparator.comparing(String::length);
获取可传递给方法的比较器实例。
这是您要搜索的内容(我相信):
public static <T, U extends Comparable<U>> int compare(T o1, T o2, Function<T, U> mapper) {
return mapper.apply(o1).compareTo(mapper.apply(o2));
}
你可以这样称呼它:
compare("str1", "str2", String::length); // 0
感谢您的回答。其实我现在想通了。我想要提供的对象实例(o1 和 o2)来执行给定的方法。我发现 Supplier 是错误的接口,我不得不使用 Function。在这里你可以看到我的工作简化示例:
public static <T> int myCompareTo(T o1, T o2, Function<T, Comparable> getter) {
return getter.apply(o1).compareTo(getter.apply(o2));
}
接口必须是 Function 而不是 Supplier 的原因是,只有 Function 等同于接受对象并调用对象上引用的方法的 lambda 表达式。
例如,如果您将方法引用定义为:
Function<TypeOfInstance, ReturnTypeOfReferencedMethod> methodReference = TypeOfInstance::referencedMethod();
那么正在执行的等效 lambda 表达式是:
(instance) -> instance.referencedMethod()
附加信息:
编辑:我知道我可以通过使用 Comparator 来完成同样的操作,但是这个例子非常简单。在我的应用程序中,这种功能是必需的。我必须创建一个 compareTo 函数来按多个属性对 ArrayList 进行排序,因为主要排序属性在列表中可能不是唯一的。我想与您分享我的代码,因为我认为这对您来说可能是一个有趣的见解。
public static <T> int ultimateCompare(T o1, T o2, Function<T, Comparable>... getters) {
for (Function<T, Comparable> getter : getters) {
int result = getter.apply(o1).compareTo(getter.apply(o2));
if (result != 0) return result;
}
return 0;
}
以这个为例,你可以按照姓氏对一个人的列表进行排序,如果其中两个相同,你可以使用名字来排序。使用此解决方案,您可以在运行时更改排序。
实际上,更正确的定义方法的方法是:
private static <T, U extends Comparable<? super U>> int myCompareTo(T left, T right, Function<T, U> fu) {
return Comparator.comparing(fu).compare(left, right);
}