Java 创建lambda表达式的字符串表示形式
出于调试目的,我尝试在Java8中创建lambda表达式的字符串表示(特别是Java 创建lambda表达式的字符串表示形式,java,lambda,tostring,java-8,predicates,Java,Lambda,Tostring,Java 8,Predicates,出于调试目的,我尝试在Java8中创建lambda表达式的字符串表示(特别是谓词s的字符串表示,尽管对于其他lambda表达式也很有趣)。我的想法是这样的: public class Whatever { private static <T> String predicateToString(Predicate<T> predicate) { String representation = ... // do magic retu
谓词
s的字符串表示,尽管对于其他lambda表达式也很有趣)。我的想法是这样的:
public class Whatever {
private static <T> String predicateToString(Predicate<T> predicate) {
String representation = ... // do magic
return representation;
}
public static void main(String[] args) {
System.out.println(Whatever.<Integer>predicateToString(i -> i % 2 == 0));
}
}
公共类{
私有静态字符串谓词字符串(谓词谓词){
字符串表示法=…//domagic
回报代表;
}
公共静态void main(字符串[]args){
System.out.println(Whatever.predicateToString(i->i%2==0));
}
}
输出将是i->i%2==0
(或逻辑上等价的东西)。toString()
方法似乎没有帮助,输出类似于com.something.Whatever$$Lambda$1/1919892312@5e91993f
(我想应该是toString()
未被覆盖)
我不确定这样的事情是否可能发生,例如,通过反射,到目前为止我肯定还没有找到任何关于它的东西。有什么想法吗?我能想到的最简单的事情就是创建一个“命名谓词”,为谓词提供一个名称或描述,基本上是任何有用的
toString
:
public class NamedPredicate<T> implements Predicate<T> {
private final String name;
private final Predicate<T> predicate;
public NamedPredicate(String name, Predicate<T> predicate) {
this.name = name;
this.predicate = predicate;
}
@Override
public boolean test(T t) {
return predicate.test(t);
}
@Override
public String toString() {
return name;
}
public static void main(String... args) {
Predicate<Integer> isEven = new NamedPredicate<>("isEven", i -> i % 2 == 0);
System.out.println(isEven); // prints isEven
}
}
一个奇怪的想法可能是推导谓词的“结构”描述,即某些给定输入的输出是什么?显然,当输入集是有限的和小的(例如,对于枚举、布尔或其他一些受限集)时,这将最有效,但我想您也可以尝试使用一组小的“随机”整数作为整数谓词:
private static Map<Boolean, List<Integer>> testPredicate(Predicate<Integer> predicate) {
return Stream.of(-35, -3, 2, 5, 17, 29, 30, 460)
.collect(Collectors.partitioningBy(predicate));
}
私有静态映射testPredicate(谓词谓词){
回流流量-35、-3、2、5、17、29、30、460)
.collect(收集器.partitionby(谓词));
}
对于
isEven
,这将返回类似{false=[-35,-3,5,17,29],true=[2,30,460]}
,我认为这并不一定比手动给它们一个描述更清楚,但对于不受您控制的谓词可能有用。调试目的?你不能只看源代码吗?那需要一个反编译器。@SotiriosDelimanolis当然我可以一直看源代码。但是如果有一个可打印的表示形式就好了。那你就不能复制源代码吗?@jeroenvanevel你的意思是每次手动编写一个字符串表示形式吗?可能,当然。但不是很优雅。虽然这应该可以工作,但lambda表达式语法的美妙之处在这里部分消失了,因为包装器对象NamedPredicate
必须使用new
操作符创建。@blalasaadri True。我想你可以通过制作一个静态工厂方法来隐藏一些丑陋的东西,比如new
和
(参见所有番石榴收集工厂方法)。我还添加了另一个想法,用于根据事实之后的任何谓词来确定排序的描述——我不确定它是否有用,但仍然可以进行有趣的探索!当然,工厂方法会改善这种情况。仍然不理想,但缺乏一种程序化的方法来提取表达式,这可能是最优雅的解决方案。我试图推广该解决方案。请看一个通用实现。
private static Map<Boolean, List<Integer>> testPredicate(Predicate<Integer> predicate) {
return Stream.of(-35, -3, 2, 5, 17, 29, 30, 460)
.collect(Collectors.partitioningBy(predicate));
}