为什么没有(标准的,Java认证的)解决方案作为Java语言本身的一部分,从Java方法返回多个值,而不是开发人员必须使用他们自己的方法,如地图,列表,对等?为什么Java不支持n元组对象?
特别考虑可能将两个对象一起修改(串联)的普通私有方法,并且在这种情况下,作为返回的类型对象听起来有点过分。
答案 0 :(得分:51)
我认为OP意味着“为什么Java不支持n元组对象?”。 Python,Haskell,Lisp,ML等具有异构的n元组功能。通常,在语言中显然返回多个对象的能力也是语法糖(即在python中返回'a','b')。
当然,理由是语言设计和一致性。 Java更喜欢非常明确,不喜欢匿名数据结构(虽然我希望我们有匿名闭包)。
例如在Java中,没有办法说我想要一个带有这些类型参数的回调并返回它。有些人认为这是一个巨大的弱点,其他人喜欢一致性和明确性。
恕我直言虽然烦人但我经常通过制作静态内联类来解决这个问题:
private static class Combo {
String name;
int weight;
}
是的,这很繁琐,但后来我经常重用和重构那些使它们成为顶级并添加行为的类。实际上,采用这种方法的一个优点是,更容易添加新字段,即匿名数据结构(如FP语言),添加字段变得更加困难(最终会更改大量代码)。
我应该注意,对于2元组,有些人使用(或滥用)java.util.Map.Entry
,因为Java 6中有java.util.AbstractMap.SimpleEntry
。还有一些人现在使用Commons Lang3's Pair support (2-tuple)。
Scala有一些n-tuple支持作弊,并且拥有一大堆2-16个元组接口,这些接口是语言中的标准接口,并且在语法上对程序员隐藏起来。
出于纯粹的教育原因,您可能希望了解其他languages accomplish this。
更新:适用于Java 8
Java 8会/也许(所以我的号码......也许叫我)支持一个名为java.lang.BiValue
的接口,其中有一个可以使用的具体实现,称为java.lang.BiVal
。这些类有助于支持新的lambda功能。但请注意,这仅适用于2元组。
更新:2015年
Java 8 没有获得元组的支持。
更新:来自作者2015
如果你仍然想要元组支持,那么有三个库可以很好地支持元组:
答案 1 :(得分:9)
Java方法返回零或一个值; 是java的标准。如果需要返回多个值,请创建一个具有多个值的对象并将其返回。
答案 2 :(得分:4)
如果要返回两个对象,通常需要返回一个封装两个对象的对象。
答案 3 :(得分:3)
有很多hackish方法可以实现这一点,一种方法是返回一个Object[]
,但是你需要担心索引,并且空指针检查,它只是变得讨厌。另一种方法是返回String
,但是你必须解析它,它变得讨厌。
我认为真正的问题是为什么?
这就是问题 - 如果我和你一起开展项目,我看到了这种行为,我会重写它,以便你可以看到它应该如何处理。如果您提供代码示例,我将重写它以进行说明。
编写您的方法只需一个责任,如果他们需要返回的数据超出他们的能力,您应该使用一个对象,或者将其分解为更小的方法。
答案 4 :(得分:1)
因为不建议从方法返回多个值(在Java中)。
如果需要方法中不相关的值,则需要使用不同的数据结构,例如包含这些值的对象。如果您需要同一个类的多个实例(即几个字符串),则需要根据需要返回数组或某些集合。
例如,使用其他语言(例如Go)返回多个值来返回错误代码,但Java使用异常进行了不同的设计。
答案 5 :(得分:1)
有一种新的模式可用,并且适用于"所有异步"您可能会在JavaScript等语言中看到的本质。
我的很多代码现在看起来像这样: - )
arr
没有要创建的新对象,也没有那么多额外的类,因为接口是对象的内部类。
这就是让Swift如此出色的原因。代码可能如下所示:
public class Class1 {
public interface Callback {
void setData(String item1, String item2);
}
public void getThing(Callback callback) {
callback.setData("a", "b");
}
}
public class Class2 {
public void doWithThing(Class1 o) {
o.getThing(new Class1.Callback() {
public void setData(String item1, String item2) {
... do something with item 1 and item 2 ...
}
});
}
}
因为唯一的论点是块,即使是这样:
o.getThing({ item1, item2 -> Void in
... do something with item 1 and item 2 ...
});
Java需要努力使回调负载代码更容易阅读。