6

所以我在这里有一个代码片段。我在和朋友讨论一些代码时遇到了这个问题

Map<Integer , List<String>> myMap = new HashMap<Integer , List<String>>();
List<String> list =  new ArrayList<String>();
myMap.put(45,list);
List<String> lst = myMap.get(45);
lst.add("String1");
lst.add("String2");
lst.add("String3");
System.out.println(myMap.get(45));

我的问题是。-> 如果可以通过另一个参考修改地图外的列表?我是从 OOP 设计的角度来问的。

4

7 回答 7

2

没关系,恕我直言

当你写

List<String> lst = myMap.get(45);

它仍然引用 , 中的值map作为 key 45

一旦你得到了值(referencelist),这取决于你用它做什么。

于 2013-10-01T09:59:22.783 回答
2

如果可以通过其他参考修改地图外的列表?我是从 OOP 设计的角度来问的。

这实际上取决于您修改它的上下文。如果您计划大量执行此操作,并使用许多不同的值,那么您很快就会发现自己的代码非常混乱,难以调试和遵循。

但是,在您的示例中,您首先从地图中加载它,然后对其进行编辑。很明显,数据来自您的Map对象。如果您通过注释和文档说明清楚,尤其是当您在其他方法之间传递此引用时,这根本不是坏习惯。

于 2013-10-01T10:01:24.210 回答
2

没关系,只要您处理好任何潜在的同步;例如,如果有多个线程可能正在修改地图和/或列表。

您可能会将此与修改关键对象的情况混淆。如果修改破坏了哈希表不变量,那显然是不行的;例如

  • 如果它导致密钥的哈希码更改,或者
  • 如果与表中使用的其他键相比,它会导致键给出不同的结果。

我是从 OOP 设计的角度来问的。

我想说OO设计在这个问题上是中立的。Map您正在使用不控制值的 Java 接口(即)。您没有违反封装,因为这些值没有被Map抽象封装。

这是否是应用角度的声音设计取决于整体设计。在不了解上下文的情况下,我们无法以一种或另一种方式做出判断。

于 2013-10-01T11:37:01.027 回答
0

每个参考都有一个范围,无论您希望通过多个参考还是通过单个参考来访问地图,都是您的选择(根据您的要求)。

于 2013-10-01T09:58:54.420 回答
0

没关系。在代码片段的第 5-7 行中将数字添加到列表后,然后在第 8 行再次从地图中获取列表后,您从地图中获取的列表将包含您刚刚添加的额外数字。

于 2013-10-01T10:01:15.883 回答
0

这取决于您想对列表做什么以及您的要求是什么。

我会说这没问题,但将它封装在另一个对象中可能会更好。考虑如何处理空列表的问题,应该删除还是保留它们?

封装将允许您确保删除空列表,因为用户将只能访问包装器,而不是直接访问列表。

顺便说一句,HashMap必须更改地图外的列表;)

于 2013-10-01T10:01:30.713 回答
0

ArrayList是可变的。它是可调整大小的,修改后保持相同的引用。要拥有不可变列表,您应该使用以下代码。

 List<String> list = Collections.unmodifiableList(new ArrayList<String>());

如果您以上述方式定义列表,则无法修改它。

于 2013-10-01T10:12:11.117 回答