繁体   English   中英

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

[英]Better to use a list of pairs, or two lists?

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

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

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

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

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

这对列表的优点:

  • 不依赖于任何非JDK类(简单,因为Pair是作为一个概念来掌握)
  • 不需要构造任何辅助对象来承载数据
  • 无论如何,调用者更有可能将参数放在单独的列表中,因此在调用方法之前不需要重新调整数据。

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

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

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

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

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

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

我还倾向于使用Pair类,引用您列出的优点:

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

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

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

使用像Pair这样的类表示意图是存在一对表示ID和实际实体本身的值。 它还表明,一个Pair对象是一个需要一起处理的离散数据单元 - 不能因为拥有两个独立的ID和实体List而感到厌烦。

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

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

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

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

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

我会去的ListPair S,如果两个整数真正属于一起,应该代表“一件事”。

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

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

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

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

我不同意这一点:

  • 不依赖于任何非JDK类(简单,因为Pair是作为一个概念来掌握)

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

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

使用对列表或地图。

我不买你列出的任何“骗局”论点。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM