从Java方法返回多个值:为什么没有n元组对象?

时间:2011-09-19 12:23:02

标签: java methods return-type

为什么没有(标准的,Java认证的)解决方案作为Java语言本身的一部分,从Java方法返回多个值,而不是开发人员必须使用他们自己的方法,如地图,列表,对等?为什么Java不支持n元组对象?

特别考虑可能将两个对象一起修改(串联)的普通私有方法,并且在这种情况下,作为返回的类型对象听起来有点过分。

6 个答案:

答案 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

如果你仍然想要元组支持,那么有三个库可以很好地支持元组:

  • javatuples - 支持JDK 5及更高版本。最多10元组。
  • JOOλ - 来自jOOQ的作者,但需要JDK 8.
  • Commons Lang 3 - 现在支持Triple(3-tuple)并支持JDK 6及以上版本。

答案 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需要努力使回调负载代码更容易阅读。