Java:将lambda存储为值的映射

Java:将lambda存储为值的映射,java,lambda,functional-interface,gosu,Java,Lambda,Functional Interface,Gosu,我想学习Java的“更新”语法和API的可能性。我指的是10+(比如说10-13)。 它主要围绕lambda的声明和在映射中存储符合相同签名的不同实现。 最近我主要与Gosu合作,我可以提供以下代码片段: var longInput = 10000000L new LinkedHashMap<String, block(long) : long>( { "byte" -> (\x -> x as byte as long), "short" ->

我想学习Java的“更新”语法和API的可能性。我指的是10+(比如说10-13)。 它主要围绕lambda的声明和在映射中存储符合相同签名的不同实现。 最近我主要与Gosu合作,我可以提供以下代码片段:

var longInput = 10000000L

new LinkedHashMap<String, block(long) : long>( {
    "byte"  -> (\x -> x as byte as long),
    "short" -> (\x -> x as short as long),
    "int"   -> (\x -> x as int as long),
    "long"  -> (\x -> x as long as long)
}).eachKeyAndValue(\key, value ->
  print("${longInput} ${value(longInput) == longInput ? "can" : "cannot"} be converted to ${key}")
)
var longInput=10000000升
新LinkedHashMap({
“字节”->(\x->x作为长度相同的字节),
“短”->(\x->x与长一样短),
“int”->(\x->x等于int的长度),
“长”->(\x->x与长一样长)
}).eachKeyAndValue(\key,value->
打印(${longInput}${value(longInput)==longInput?:“不能”}转换为${key}”)
)
我可以在Java 10中进行类似的操作:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        long longInput = 10000000L;

        var conversions = new LinkedHashMap<String, Conversion<Long>>();
        conversions.put("byte",  (x) -> (long) (byte)  x.longValue());
        conversions.put("short", (x) -> (long) (short) x.longValue());
        conversions.put("int",   (x) -> (long) (int)   x.longValue());
        conversions.put("long",  (x) -> (long) (long)  x.longValue());

        conversions.forEach((key, value) -> {
            System.out.printf("%d %s be converted to %s%n", longInput, value.convert(longInput) == longInput ? "can" : "cannot", key);      
        });
    }
}

interface Conversion<T> {
    T convert(T input);
}
import java.util.*;
公开课考试{
公共静态void main(字符串[]args){
长期输入=10000000升;
var conversions=newlinkedhashmap();
转换.put(“byte”,(x)->(long)(byte)x.longValue());
转换.put(“short”,(x)->(long)(short)x.longValue());
转换.put(“int”,(x)->(long)(int)x.longValue());
转换.put(“long”,(x)->(long)(long)x.longValue());
转换。forEach((键,值)->{
System.out.printf(“%d%s被转换为%s%n”,longInput,value.convert(longInput)=longInput?“可以”:“不能”,键);
});
}
}
接口转换{
T转换(T输入);
}
我的问题是:

  • 它是否可以在没有命名接口的情况下,以类似于Gosu中的“匿名”功能方式完成
  • 还有什么能让Java更简洁的吗
  • 更新: 这只是一些游戏代码,其目的是将原语long转换为较小的类型并返回。灵感来自。所以从我的角度来看,我想留下来

    使用答案,我当前的Java 10代码如下所示:

    public class Test { 
        public static void main(String[] args) {
            var longInput = 10000000L;
    
            new LinkedHashMap<String, UnaryOperator<Long>>() {{
                put("byte",  (x) -> (long) (byte)  x.longValue());
                put("short", (x) -> (long) (short) x.longValue());
                put("int",   (x) -> (long) (int)   x.longValue());
                put("long",  (x) -> (long) (long)  x.longValue());
            }}.forEach((key, value) -> {
                System.out.printf("%d %s be converted to %s%n", longInput, value.apply(longInput) == longInput ? "can" : "cannot", key);        
            });
        }
    }
    
    
    公共类测试{
    公共静态void main(字符串[]args){
    var longInput=10000000升;
    新LinkedHashMap(){{
    put(“byte”,(x)->(long)(byte)x.longValue());
    put(“short”,(x)->(long)(short)x.longValue());
    put(“int”,(x)->(long)(int)x.longValue());
    put(“long”,(x)->(long)(long)x.longValue());
    }}.forEach((键、值)->{
    System.out.printf(“%d%s被转换为%s%n”,longInput,value.apply(longInput)=longInput?“可以”:“不能”,键);
    });
    }
    }
    
    它是否可以在没有命名接口的情况下以类似的方式完成 像Gosu中那样的“匿名”功能

    Java已经有了一个类似于您定义的功能接口。您可以在
    映射中使用
    UnaryOperator

    还有什么能让Java更简洁的吗

    我认为这样读起来会更好:

    Map<String, UnaryOperator<Long>> conversions = new LinkedHashMap<>();
    conversions.put("byte", a -> (long) a.byteValue());
    conversions.put("short", a -> (long) a.shortValue());
    conversions.put("int", a -> (long) a.intValue());
    conversions.put("long", a -> a); // UnaryOperator.identity()
    
    Map conversions=newlinkedhashmap();
    conversions.put(“byte”,a->(long)a.byteValue());
    转换.put(“short”,a->(long)a.shortValue());
    conversions.put(“int”,a->(long)a.intValue());
    转换。放置(“long”,a->a);//UnaryOperator.identity()
    
    不直接知道答案,但请注意,您可以将接口定义移动到
    测试
    类定义中,这样它就不会占用文件/干扰包中类的功能。没错,谢谢@Naman建议,实际上这个接口已经作为java.util.function.UnaryOperator存在于库中,因此可以避免这种情况。感谢UnaryOperator。从我想尝试的角度来看,它是功能接口的扩展,这已经很好了。特别是在最初的形式中,我编写了int->boolean lambda,其中需要更一般的函数形式。但我仍然看到需要这些具体的接口来将其存储在集合中,因为该语言还没有语法支持。关于双重转换,它是故意进行的,因为它是为了检查primitive long上的这种转换行为(primitive long不能在Java泛型中使用,因此这就是.longValue()调用的原因)。通常情况下,我同意这些函数返回所需的基本类型,或者在长时间的情况下避免任何转换。顺便说一句,我的练习受这个简单问题的启发@MarekPulka True,必须有一个推断的表示类型。即使考虑使用双括号初始化映射,如<代码> var转换=新的LINKEDHASMAP(){{(字节),->(long)A.ByTealValue());放置(“短”,->(long)A.Sql());放置(“int”,->(long).int值());放置(“long”,-> a);};code>,您不能使用方法
    byteValue()
    或类似的方法,除非它们位于
    对象
    类级别。是的,您是对的。我忘了这部分是练习“如果发生什么”部分的一部分,所以我同意这不是最佳的,但这是有意的。我刚才在问题中加了这句话。@MarekPulka,但在Java中使用它时,你肯定应该阅读