最好使用一对或两个列表?

时间:2009-09-22 08:31:18

标签: java collections interface

我正在编写一个构成Java类公共接口一部分的方法。它广泛允许调用者指定要分配给多个数据库实体的值 - 因此它们必须提供实体本身的ID以及要分配给它们的值。

我在将此实现为List<Pair<Integer, Integer>>或仅仅两个List<Integer>参数之间摇摆不定。两者都显然工作,并且在我的方法中都不会导致任何实现或效率问题。它在任何情况下都基本相同( 2xn 数组),只是条纹不同。

所以我想对你认为哪一个会更好,以及为什么会有一些意见。

到目前为止我看到的对列表的优点:

  • 更准确地反映实体之间的实际关系
  • 消除某些类别的动态错误(例如列表长度不匹配)

这对列表的优点:

  • 不依赖于任何非JDK类(简单如Pair所掌握的那样)
  • 不需要构建任何辅助对象来承载数据
  • 无论如何,调用者更有可能将参数放在单独的列表中,因此在调用方法之前不需要重新对齐数据

两种情况都具有相同的类型安全性,以及参数不匹配的相同可能性(例如,首先输入值,而当它应该相反时输入ID秒)。后一个问题可以通过在Integer周围创建一个简单的包装器来调用,这个包装器叫做PrimaryKey,它有自己的优点和缺点,无论如何都与这个问题正交,因为这两者都可以同时使用例。

然而,有一个中间立场可能成为第三个选择 - 一个简单的容器类,其中包含objectId和value的整数字段。这并没有使编译器帮助确保通过键入来确保对象是正确的,但它确实在赋值中提供了额外的安全层。我不认为我会这样做,因为我不喜欢用像这样的普通类来污染公共接口的想法。

11 个答案:

答案 0 :(得分:23)

强烈建议将这些数据捆绑在一起,可能是一对,但更多是作为一个特定的容器。这样你就可以自由地引入与这两个对象相关的额外功能。

保持两个列表分开将是一个痛苦。你必须将两者一起传递并使它们保持同步。为此创建新对象的开销可以忽略不计,而且正是OOP的设计目标(您只需为应用程序编写新的Java代码就可以创建非JDK类,不要忘记)。

我一直在创建像这样的小班。它们强制实施强大的类型安全性,并提供增强和重构的范围。 IDE可以更容易地识别和执行重构。

答案 1 :(得分:5)

我觉得你所经历的分析已经很好地确定了两种方法的优缺点。

我还倾向于使用Pair类,并列举了您列出的优势:

  
      
  • 更准确地反映了实际情况   实体之间的关系
  •   
  • 消除某些动态类别   错误(例如列表长度不匹配)
  •   

对我来说最重要的是最重要的一个。

始终编写演示意图的代码。不要仅仅考虑实施来编码。

使用类似Pair的类显示了一对值,它们代表一个ID和实际实体本身。它还表明,一个Pair对象是一个需要一起处理的离散数据单元 - 不能因为拥有两个独立的List个ID和实体而感到不适。

答案 2 :(得分:5)

为什么不选择字典(地图类型,现在Java调用它,我认为它曾经是Hashtable)?这会将ID映射到值并避开您的困境。

答案 3 :(得分:2)

当API公开时,请确保您只是实现核心功能,因为您提供给客户端的所有内容都无法收回。

考虑一个只有2个参数赋值的方法(Integer entityId,Integer someOtherId),让客户想出如何添加更多项目。

如果你想允许方便的访问,给它们一个带有接口“Assignment”的util类,它只定义了getEntityId()和getSomeOtherId(),并带有一个默认实现,比如DefaultAssignment,它保存了对id的最终引用。

然后您的客户可以选择他们想要的方式,而您无需确保支持您的“配对”课程。

答案 4 :(得分:2)

如果两个整数真的属于一个并且应该代表“一件事”,我会选择List Pair s。

使用两个单独列表的另一个缺点是,如果列表总是大小相同,编译器不会检查您。然后你将解释留给你方法的客户;客户需要匹配两个列表中的元素。

我没有看到使用像Pair这样的类作为一个很大的缺点“,因为它依赖于非JDK类”,正如你所说,但如果你真的不想使用像{{{{{ 1}},你甚至可以把它作为一个数组列表:Pair,其中每个数组包含两个List<Integer[]>对象。 (在我看来,这比使用Integer更加丑陋。)

答案 5 :(得分:2)

列表对方法是显而易见的,因为它更准确地反映了意图 - 但如果ID是唯一的,Map可能会更好。

如果您有百万这些对,并且内存消耗成为主要考虑因素,您可能希望切换到列表对(因为会有一对)每对较少的对象)。

答案 6 :(得分:1)

我不同意这一点:

  • 不依赖于任何非JDK类(简单就像对象是作为概念所掌握的)

因为虽然JDK中没有Pair类,但是有一个接口:Map.Entry,它适合您作为键/值关联的预期用途。

答案 7 :(得分:0)

在我看来,请使用对列表(或您自己更具体的容器),因为这似乎是最自然地反映您正在解决的问题。并且它只是一个变量来跟踪和发送到方法,而不是两个。

答案 8 :(得分:0)

使用对应列表或地图。

我不会购买您列出的任何“骗局”参数。

你应该总是站在更大抽象的一边。你正在编写一种面向对象的语言,在我看来,封装和信息隐藏是思考对象的最重要原因。它隐藏了用户的实现细节,让他们专注于您的课程提供的内容。他们可以忘记你的班级如何完成他们想要的东西。强迫您的客户维护两个列表,要求他们了解更多信息。

答案 9 :(得分:0)

首先编写单元测试。然后,您可以轻松查看最容易使用的内容,然后选择它作为您的实现。

答案 10 :(得分:0)

您可以考虑将参数设为Iterator<Pair>。如果调用类具有List<Pair>,则获取迭代器是微不足道的。如果不是,则创建迭代器可能更容易构造,更快和/或更自然。在某些情况下,它甚至可以帮助您消除内存不足的问题。