【问题标题】:How to return a pair of objects in one method? [duplicate]如何在一个方法中返回一对对象? [复制]
【发布时间】:2014-12-16 21:10:28
【问题描述】:

在 java 的一个方法中返回一对对象的 (1) 常见做法和 (2) 可能的解决方案是什么?

示例:假设我在 Model 中有一个 CheckersBoard 类,它有一个方法 f 接受 BoardFieldIndex start, BoardFieldIndex end 描述 View 要求的运动并返回一对 Figure f(如果 start 被占用) 和MovementVector v(如果它在董事会上是合法的)。

在 C++ 中,我有两个流行的选择:

(一)

Figure *f; MovementVector *v;
board.f( start, end, f, v );

(二)

Figure *f; MovementVector *v;
std::Pair<Figure*, MovementVector*> tuple = board.f( start, end );
f = tuple.first; v = tuple.second;

在 Java 中,我能想到的唯一解决方案是:

  1. 使用列表代替元组。但问题是我没有在那里定义类型,并且我认为不鼓励使用原始列表。
  2. 实现自定义泛型类 Pair。

我想知道最佳实践是什么,或者我怎样才能以一种对 Java 来说很自然的方式来做到这一点。我个人最喜欢(I.),但在这里是不可能的。我在其他解决方案中遇到的问题是,我访问元组元素的方式并不暗示它们包含什么,而且我认为这有点违背文学编程范式。

【问题讨论】:

标签: java tuples


【解决方案1】:

您可以为实现Map.Entry&lt;Figure,MovementVector&gt; 的两个对象定义一个内部容器,然后使用getKey() 获取图形对象并使用getValue() 获取MovementVector。例如:

private class MyEntryClass<K,V> implements Map.Entry<K,V> {
    private final K key;
    private V value;

    public MyEntryClass(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }

    public V setValue(V value) {
        V old = this.value;
        this.value = value;
        return old;
    }
}

然后(假设 f 是您的 Figure 并且 v 是您的 MovementVector)您可以返回 new MyEntryClass&lt;Figure,MovementVector&gt;(f,v);

编辑:为了可扩展性/通用性,将类参数设为通用

【讨论】:

  • 恕我直言,这是一个非常有趣的解决方案,谢谢!
  • 我更喜欢这个解决方案。我建议使用它。
  • 为什么MyEntryClass还需要类型参数?如果它们总是FigureMovementVector(正如您在implements Map.Entry&lt;Figure, MovementVector&gt; 中指出的那样),您可以通过使MyEntryClass 非泛型来简化事情。
  • 这很公平。如果他/她想要使其成为通用类型的数据结构,我将通用类型留在其中,但根据问题细节对其进行参数化。它可以保持通用或丢失参数
  • 为什么不直接使用AbstractMap.SimpleEntry,它已经为您做到了?
【解决方案2】:

你只能返回一个事物,你不能返回多个对象,除非它们被存储在一个数组中并且你返回的是实际的数组。

最好将对象简单地存储在List&lt;T&gt; 中,然后在方法中简单地返回List。从中您可以直接检索该数组中所需的任何元素。

我还意识到您提到了 pair 对象。如果您希望在特定结构中存储和检索对象,您可以创建(按照 Max 的建议)自定义 DTO 类并简单地返回它。

【讨论】:

  • 如果要返回的两个对象属于不同类型,则您将面临原始类型列表或未经检查的添加操作的风险
  • @Tgsmith61591 - 没错,我的回答是针对运行相同类型的想法
【解决方案3】:

Apache 的 Common-Lang 已经 defines a Pair 输入方便,如果你想使用它。 tuple 子包也有 defines a lot of useful containers

也就是说,我想说像这样的情况需要一个对象将这两个值封装在一起;如果您需要同时返回它们,那么从长远来看,使用比Pair&lt;Figure, MovementVector&gt; 更有意义的包装器可能对您更好。

【讨论】:

    【解决方案4】:

    我能想到的基本选项至少有 4 个:

    1. 返回List&lt;Object&gt;Object[]

    2. 从非核心库返回 PairTuple 类。 公共方法可能不应该这样做,因为 getter 的名称毫无意义。

    3. 创建您自己的自定义类型并将其返回。 这通常是最好的解决方案。

    4. 允许方法参数之一是可变的。 例如,如果要返回 3 个doubles 和一个String,则可以将方法参数之一设为double[] arr。然后该方法可以将值分配给arr[0]arr[1]arr[2],并返回一个String。这有点笨拙,但有时很有用。

    【讨论】:

      【解决方案5】:

      如果您要返回两种不同的类型,我绝对不建议您使用 List,因为您提到自己的类型原因。我的建议是创建一个结果/响应类型,例如

      Tuple<Figure,Movement>
      

      或重复使用Map.Entry

      另外,请阅读this question and answers

      干杯,

      【讨论】:

      • List 在我看来也是一个糟糕的解决方案,我之所以提到它是因为我在网上看到了它的建议。
      猜你喜欢
      • 1970-01-01
      • 2014-08-02
      • 2020-10-11
      • 2021-07-15
      • 1970-01-01
      • 2023-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多