【问题标题】:returning multiple values in Java在Java中返回多个值
【发布时间】:2012-05-13 19:23:21
【问题描述】:

序言:我知道使用列表或其他集合来返回结果,但是我必须通过列表来提取结果:请参阅第二个示例

Preamble-2:我正在寻找“Java 不支持此功能......”之外的答案


我正在寻找一种从 Java 方法调用中返回多个对象的便捷方式。

有点像 PHP:

list ($obj1, $obj2, ...) foobar();

我真的厌倦了在参数中传递持有者对象,例如:

class Holder {
   int value;
}

Holder h1=new Holder();
Holder h2=new Holder();

然后:

o.foobar(h1,h2);

...如果有人想出一个优雅的方法来解决这个问题,我会非常感兴趣。


使用列表

List<String> = foobar();

这样做有两个缺点:

我必须先在房子的被叫方打包列表:

// this is on the callee side of the house
ArrayList<String> result = new ArrayList<String>
result.add("foo");
result.add("bar");

然后在调用方我必须提取结果:

// This is on the caller side
List<String> result = foobar();
String result1 = result.get(0);
String result2 = result.get(1); // this is not as elegant as the PHP equivalent

此外,假设我想返回不同类型的对象,比如 String、Integer,我将不得不返回一个对象列表,然后强制转换每个对象......不漂亮

谢谢。

【问题讨论】:

  • 我只是返回一个列表
  • 返回List有什么问题?
  • 已编辑。 Java 的“老手”不会问这个问题,而且原来的问题有点刻薄。
  • @Adam-Liss -- 也许比你还老手 :-( ... 幼稚的回应!!!
  • 如果不支持,则不支持。就那么简单。您可以使用具有众所周知的缺点的数组或其他集合 - 特别是使用不方便的样板来放置列表。改用 scala,你会得到元组。当然,您可以使用 Java 中的元组,但不能以那种优雅的方式。

标签: java return-value


【解决方案1】:

使用通用元组类是我能想象的最接近的。给出一个想法,这样的三个返回值的通用类可能看起来像这样:

public class T3<A, B, C> {
    A _1;
    B _2;
    C _3;
    T3(A _1, B _2, C _3) {
        this._1 = _1;
        this._2 = _2;
        this._3 = _3;
    }
}

这允许在被调用方使用单语句构造函数,例如:

public T3<String, Integer, Character> getValues() {
    return new T3<String, Integer, Character>("string", 0, 'c');
}

但是没有被调用者构造持有者实例。

每个返回值的数量都需要一个自己的元组类。 Functional Java library 中可能提供了类似的内容。作为参考,这里有一个N-Tuple implementation

对于二值情况 java.util.AbstractMap.SimpleEntry 会这样做:

return new SimpleEntry<String, Integer>("string", 0);

不管怎样,我看到了多个返回值需要考虑的两个重要点:

  1. 类型化的返回值
  2. 指出每个返回值的含义

虽然很无聊,但我建议创建一个单独的类来保存所有响应值并将其声明为方法返回类型。这样可以突出显示每个值的含义。

【讨论】:

    【解决方案2】:

    你可以有一个像这样签名的方法:

    List<Holder> foobar();
    

    【讨论】:

      【解决方案3】:

      您能否返回ListSetMap

      【讨论】:

      • 我可以,但这是一个相当麻烦的解决方案——请参阅我的问题中的示例 2
      【解决方案4】:

      返回一个扩展的 Holder 似乎比返回一个 List 更好:

      class Holder {
          int value1;
          String value2;
          Holder(int value1, String value2) {}
      }
      
      Holder foobar() {
          return new Holder(1, "bar");
      }
      

      【讨论】:

      • 是的,可能是冗长的冗长 :-(,感谢您的回复
      • @user1172468 冗长是 Java 的固有属性。有时我渴望 C++ typedef 和 operator 重载魔法,但它们会弄得一团糟,所以我很高兴 Java 很冗长。
      【解决方案5】:

      如果您需要返回多个相同类型的值,那么 List 或 Set 是合适的。例如,将可变长度的用户名列表作为列表返回是完全有效的。如果你知道你总是要返回固定数量的值,我会使用一个数组。例如,在将某种用户 ID 作为三个不同整数返回的方法中,我会使用:

      public int[] getUserId(){
          int[] returnArray = new int[3];
          returnArray[0] = getFirstPart();
          returnArray[1] = getSecondPart();
          returnArray[2] = getThirdPart();
      
          return returnArray;
      }
      

      在调用者代码中,获取值就像array[0]array[1]array[2]一样简单。这比 Collection 容易得多,而且您不会破坏任何东西,因为用户 ID 被定义为三个整数。

      如果你真的需要返回多个不同的值,那么持有者类是最好的选择,没有其他办法。 Java 不支持多个返回值。但我宁愿从设计的角度来看解决方案。如果一个类需要返回多个不同的值,那么它可能会做很多事情,其中​​一些与其他无关。一段代码(一个类、一个方法)应该总是有一个明确的目的和明确定义的职责。与其返回多个不同的值,我会考虑将方法拆分为多个较短的方法或定义一个接口来外部化所有功能。如果这些返回值以任何方式相关并且如果分开就没有意义,那么我认为它们应该有自己的类。

      【讨论】:

        【解决方案6】:

        您可以为此目的使用任何Collection 类。这个Lesson 可以帮助您确定最适合您的方式。

        【讨论】:

        • 嗨,感谢您的回复,我知道这一点,我已经澄清我正在寻找任何典型的补救措施。
        猜你喜欢
        • 2012-11-03
        • 2017-08-30
        • 2011-08-02
        • 2013-05-12
        • 2011-06-12
        • 1970-01-01
        • 2021-07-05
        相关资源
        最近更新 更多