创建lambda表达式的字符串表示形式 [英] Creating String representation of lambda expression

查看:208
本文介绍了创建lambda表达式的字符串表示形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于调试目的,我试图在Java 8中创建lambda表达式的字符串表示(特别是 Predicate s,尽管它对其他lambda表达式也很有意义)。我的想法是这样的:

  public class Whatever {

private static< T> String predicateToString(Predicate< T>谓词){
字符串表示= ... //执行magic
返回表示;
}

public static void main(String [] args){
System.out.println(Whatever。< Integer> predicateToString(i - > i%2 = = 0));
}

}

输出为 i - > i%2 == 0 (或逻辑等效的东西)。 toString()方法似乎无济于事,输出就像 com.something.Whatever$$Lambda $ 1 /1919892312@5e91993f (我猜这是预料为 toString()未被覆盖)。



<我不确定这样的事情是否可能,例如有了反思,到目前为止,我当然无法找到任何东西。任何想法?

解决方案

我能想到的最简单的事情是创建一个命名谓词,为你的谓词命名或者描述,基本上任何有用的 toString

  public class NamedPredicate< T>实现Predicate< T> {
私人最终字符串名称;
私人最终谓词< T>谓语;

public NamedPredicate(String name,Predicate< T>谓词){
this.name = name;
this.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); //打印isEven
}
}

可以给出谓词名称或描述这样使你使用它们的代码也更容易理解:

  Stream.of(1,2,3, 4)
.filter(isEven)
.forEach(System.out :: println);

一个陌生人的想法可能是导出谓词的结构描述,即输出是什么对于某些给定的输入?显然,当输入集有限且很小时(例如对于枚举,布尔值或其他一些限制集),这将最有效,但我想你也可以为整数谓词尝试一小组随机整数:

  private static Map< Boolean,List< Integer>> testPredicate(谓词<整数>谓词){
返回Stream.of(-35,-3,5,5,17,29,30,460)
.collect(Collectors.partitioningBy(谓词)) ;
}

对于 isEven ,这将返回类似 {false = [ - 35,-3,5,17,29],true = [2,30,460]} 的内容,我不知道我认为必须比手动给他们描述更清楚,但对于不受你控制的谓词可能有用。


For debugging purposes I am trying to create string representations of lambda expressions (specifically of Predicates, though it would be interesting for other lambda expressions too) in Java 8. My idea would be something like this:

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));
    }

}

And the output would be i -> i % 2 == 0 (or something logically equivalent). The toString() method seems to be of no help, the output is just something like com.something.Whatever$$Lambda$1/1919892312@5e91993f (which I guess is to be expected as toString() is not overridden).

I'm not sure whether something like this is even possible, e.g. with reflection, I certainly haven't been able to find anything on it so far. Any ideas?

解决方案

The simplest thing I could come up with is creating a "named predicate" that gives your predicates a name or description, basically anything that will be useful as a 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
    }
}

Arguably giving your predicates names or descriptions like this makes the code where you use them a bit easier to understand also:

Stream.of(1, 2, 3, 4)
        .filter(isEven)
        .forEach(System.out::println);

A stranger idea might be to derive a "structural" description of the predicate, i.e. what is the output for some given inputs? Obviously this would work best when the input set is finite and small (e.g. for enums, booleans or some other restricted set), but I guess you could try a small set of "random" integers for integer predicates as well:

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));
}

For isEven, this would return something like {false=[-35, -3, 5, 17, 29], true=[2, 30, 460]}, which I don't think is necessarily clearer than if you manually give them a description, but is perhaps useful for predicates that are not under your control.

这篇关于创建lambda表达式的字符串表示形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆