【问题标题】:java - return two results in one function call? [duplicate]java - 在一个函数调用中返回两个结果? [复制]
【发布时间】:2012-03-09 08:24:36
【问题描述】:

我正在尝试做这样的事情:

 public void <String,int> getItem
 { 
   return <"Jen",23>;
 }

我知道我可以使用自定义类,但是我将如何在一个函数调用中返回两个结果。

1 - 上述模板函数在 java 中是否可行,调用者如何获取它的第 1 部分和稍后的第 2 部分。

2 - 我可以使用 actionscript 中的关联数组吗?

3 - 我可以使用某种哈希图吗?

4 - 还有其他可能的方法

我尝试了所有三种方式,但一种方式或另一种语法正在打击我。所以如果有人能给出明确的例子

【问题讨论】:

  • 你做了一个简单的类包装器,然后实例化并返回它......有理由不这样做吗?
  • 不,你不能从一个方法返回两个东西。即使是假装你可以的脚本语言也将所说的东西包装在一个列表或数组中。
  • 只是玩玩,懂编程术语

标签: java


【解决方案1】:

Java 函数总是返回单个值,因此您唯一的选择是返回包含多个值的“集合”对象,例如数组或正确的Collection。例如:

public Object[] getItem() { return new Object[] { "Jen", 23 }; }
public Collection<Object> { return Arrays.asList("Jen", 23); }

虽然,Java 中的一个典型模式是返回一个封装了您的值的自定义类型,例如:

public class NameAge {
  public final String name;
  public final int age;
  public NameAge(String name, int age) {
    this.name = name;
    this.age = age;
  }
}
// ...
public NameAge getItem() { return new NameAge("Jen", 23); }

或更笼统地说:

public class Pair<X, Y> {
  public final X x;
  public final Y y;
  public Pair(X x, Y y) {
    this.x = x;
    this.y = y;
  }
}
// ...
public Pair<String,Integer> getItem() {
  return new Pair<String,Integer>("Jen", 23);
}

当然,如果您想将这些自定义类型用作散列键,那么散列(相等和散列码)会产生严重的影响。

【讨论】:

    【解决方案2】:

    我喜欢使用泛型!创建您自己的类并返回它的一个实例:

    public class Tuple<T,V>
    {
      public T item1;
      public V item2;
      public Tuple(T i1, V i2)
      { 
         item1 = i1;
         item2 = i2;
      }
    }
    

    然后你创建你的方法:

    public Tuple<String, int> getItem()
    {
       return new Tuple<String, int>("Jen", 23);
    }
    

    【讨论】:

    • 也是我的选择......而且很容易将其扩展到三人组、四人组等。
    • 很好,我喜欢这个,但是我仍然需要两个函数调用来访问元组中的项目?
    • 您可能希望将item1item2 设为最终版本。
    • 是的,但是我们可以将此版本称为Pair 而不是Tuple,因为Tuple 暗示它可以有任意数量的元素,而不仅仅是两个。
    【解决方案3】:

    Java 不允许多个返回语句。我认为最好的做法是创建一个自定义对象。你在这里所拥有的暗示了某种 Person 类,一个 la

    public class Person {
      int Age;
      String Name;
    }
    

    返回一个对象会让你所做的事情更加直观。

    【讨论】:

      【解决方案4】:

      您可以返回一个 Bundle。

      public Bundle getItem(){
         Bundle theBundle = new Bundle();
         theBundle.putString("name","Jen");
         theBundle.putInt("age",23);
         return theBundle;
      }
      

      【讨论】:

      • nice :),很高兴你给出了这个答案。我希望我也能给你一个点
      • 除非您需要特定于 Bundle 的功能,否则您不会使用 Bundle。而是对少量项目使用 ArrayMap(构建 Bundle)。或者为了获得最大效率,如果其有限的容器功能足够,请使用 SimpleArrayMap。或者,如果您要返回数百个项目,请使用 HashMap。
      【解决方案5】:

      通常,如果您需要从一个函数返回两个值 - 它是 code smell。尝试重构您的代码,以便每个函数始终只返回一个值。请记住,没有返回值 (void) 也是代码异味,但不那么重要。

      【讨论】:

      • 我强烈反对。在设计类的 API 时,重要的是匹配类的客户端需要执行的任务。考虑每个方法只返回一个值会适得其反。更糟糕的是,它通常会生成一个反映对象内部的 API,因为这是一次返回一个值的最简单方法。不要走这条路。另一方面,我同意定义新的内部类来包装多个值,而不是使用一些通用的元组解决方案。因此,我同意创建此类类的重构是减少代码异味。
      【解决方案6】:

      正确的方法是为您的返回集创建一个类:

      public class ReturnSet {
          private String str;
          private int num;
      
          public ReturnSet(String _str, int _num) {
              str = _str;
              num = _num;
          }
      
          //add getters and setters
          ...
      }
      

      那么你的函数看起来像

      public ReturnSet getItem() {
          ...
          return new ReturnSet(strValue, intValue);
      }
      

      当然,你可以通过让你的函数返回一个Object 的数组来捏造事情,但这将是一个相当糟糕的代码:

      public Object[] getItem() {
          Object[] result;
          //allocate it, get data;
          ...
          result[1] = strValue;
          relult[2] = new Integer(intValue);
          return result;
      }
      

      您甚至可以返回一个包含一个元素的哈希图:

      public Map getItem() {
          Map result;
          //allocate it, say as hashmap, get data;
          ...
          result.put(strValue, new Integer(intValue));
          return result;
      }
      

      然后在调用者中,地图的键将是第一部分,值将是第二部分。

      虽然可能有很多方法可以做到这一点,但第一种是正确的方法。

      【讨论】:

        【解决方案7】:

        如果一个方法返回一些东西,那么它的返回类型必须是这个东西:

        public MyCustomObject getItem();
        

        public Object[] getItem():
        

        或任何其他可以存储结果的地方。

        但是 Java 是一种静态类型的 OO 语言。自定义类是要走的路。

        【讨论】:

          【解决方案8】:

          您还可以通过使用“return”参数以常规方式返回一个值和其他值:

          class C {
              Type2 value; // omitted getter and setter for brevity
          }
          Type1 f1(C returnParameter, String otherParameters...)
          {
              // function body here
              returnParameter.value=returnValue2; // store the second result
              return returnValue1; // return the first result
          }
          
          // usage
          Type1 result1;
          Type2 result2;
          C helper = new C();
          result1=f1(helper, "foo", "bar");
          result2=helper.value;
          

          要获得更多结果,请使用多个“帮助”对象或一个可以保存多个值的对象。

          我自己正在寻找一个最优雅的解决方案(在我的例子中,一个返回类型是一个集合,另一个是一个整数 - 它的任何变体都可以)。

          【讨论】:

          • 几乎是-1。不要这样做,除非你有充分的理由这样做。其他一些语言具有良好的语法,可以使返回参数清晰且合理使用。 Java 没有。在 Java 中,如果定义一个新类来保存所有返回值,并返回一个保存它们的新对象,那就更清楚了。如其他答案所示。
          • 然而IS是一种返回参数有意义的优化情况:一个被多次调用的方法,以及一个可以在每个参数上重复使用相同参数的调用者称呼。避免每次调用创建临时对象。在这种情况下,将返回类型设为 void -- 将所有结果作为返回参数返回。并在方法中添加 DOC COMMENT,解释此类参数的正确用法。
          猜你喜欢
          • 2015-09-27
          • 2021-07-15
          • 1970-01-01
          • 1970-01-01
          • 2013-11-13
          • 2016-12-08
          • 1970-01-01
          • 2015-08-19
          • 2017-05-16
          相关资源
          最近更新 更多