Java:将lambda存储为值的映射
我想学习Java的“更新”语法和API的可能性。我指的是10+(比如说10-13)。 它主要围绕lambda的声明和在映射中存储符合相同签名的不同实现。 最近我主要与Gosu合作,我可以提供以下代码片段: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" ->
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输入);
}
我的问题是:
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中使用它时,你肯定应该阅读