Java 为什么List.remove会如此重载?
两个不明确的Java 为什么List.remove会如此重载?,java,api,list,collections,Java,Api,List,Collections,两个不明确的列表是否有历史原因。是否删除 对我来说,这似乎是个糟糕的设计。 对于列表来说,它似乎真的很混乱 编辑: 每个人似乎对此都很满意。让我精确一点 假设我有一个列表 虽然idx是一个对象,但Java编译并删除索引2中的项 现在,如果它是一个列表,同样的代码将调用一个具有完全不同行为的不同方法 我们不要讨论泛型会发生什么 我觉得不同的行为意味着不同的名字是一条宝贵的规则,尤其是在同一个类中。什么,这一点都不含糊。一个在指定索引处删除,另一个在列表中首次找到对象的位置删除该对象。。。哦
列表是否有历史原因。是否删除
对我来说,这似乎是个糟糕的设计。
对于列表
来说,它似乎真的很混乱
编辑:
每个人似乎对此都很满意。让我精确一点
假设我有一个列表
虽然idx
是一个对象,但Java编译并删除索引2中的项
现在,如果它是一个列表
,同样的代码将调用一个具有完全不同行为的不同方法
我们不要讨论泛型会发生什么
我觉得不同的行为意味着不同的名字是一条宝贵的规则,尤其是在同一个类中。什么,这一点都不含糊。一个在指定索引处删除,另一个在列表中首次找到对象的位置删除该对象。。。哦
编辑-方法的定义不仅仅是名称。参数的类型和数量是定义的一部分。当您使用整个方法定义时,没有歧义。其中一个用于从特定索引中删除
另一种是删除对象,索引并不重要 这怎么会模棱两可呢?每种方法的文档对我来说都很清楚:
E删除(整数索引)
删除此列表中指定位置的元素(可选操作)
布尔删除(对象o)
删除此列表中第一个出现的指定元素(可选操作)。如果此列表不包含该元素,则它将保持不变
它们做两件完全不同的事情,因此两者都需要。首先:
- 删除指定索引处的元素,然后
- (或)删除指定的元素
我不确定这是否已经为人所知,但为了完整起见,我想我应该提一下
需要注意的一个重要部分是,API比泛型(更重要的是)自动装箱早了很多(集合API是在Java1.2中引入的,自动装箱是在Java5中引入的)
因此,当他们第一次设计API时,绝对没有办法将两者混淆。即使您的列表
包含整数
对象,也很简单:如果您使用基本参数类型(int
)调用方法,那么它就是索引,如果您传入一个对象
(即使它是整数
),那么您传入要删除的对象
诚然,这仍然不是最好的想法(但有相当多的JavaAPI……不够完美),但在当时,混淆的可能性要小得多
只有当int
/Integer
屏障由于自动装箱和自动取消装箱而变得不那么明显时,混淆的可能性才会增加
旁注:CollectionsAPI的一个重要“特性”是“常用方法的简短名称”。以前的/solution“解决方案”对于非常常见的操作有着臭名昭著的长名称:
Vector.elementAt()
vs.List.get()
Vector.addElement()
vs.Collection.add()
Enumeration.hasMoreElements()
/nextElement()
vs.Iterator.hasNext()
/next()
Vector.removeElement()
vs.Collection.remove()
Vector.removeElementAt()
vs.List.remove(int)
最后一个例子是他们可能走得有点太远了。是的,这个确切的例子经常被引用为一个例子,说明出于良好目的的语言更改(泛型、自动装箱)是如何相互结合的,以及如何与现有的API结合以产生错误的。事实上,Josh希望他给了这些方法不同的名称,但是当这个接口第一次被创建时,从来没有想到对象和int之间会有任何冲突。你可以在Java拼图中找到这个问题的探索(Bloch/Gafter).歧义恰恰是指两个不同的事物具有相同的名称。它与设计无关,只是你可能会说的不好的命名。@fmucar:我认为命名是API设计中相当重要的一部分<代码>集合
如果我被称为ThingThatHoldsMultiplesOfOtherThings
,那就不一样了。我从来没有说过这不重要,如果你把集合称为ThingThatHoldsMultiplesOfOtherThings,那是你的错,而不是设计缺陷/错误。你可以称它为objectCollection,CollectionofObject,Object,objectList,objectSet。。。这不是设计,而是编码惯例。开发人员有责任给好的名字,而不是设计师/架构师。所以我想说的是,命名可能不好,是的。也许它应该被称为removeAtIndex(int)或更容易理解的东西,而不是remove(int)。对于列表
,删除列表中的int的合适方法是使用remove(Integer.valueOf(number))
。是的,我需要两者,但我希望它们有不同的名称(removeAt?removeValue?)@poulejapon,首先,我会把你的评论标记为侮辱。第二,拥有具有不同参数/参数类型的多个方法是一种标准的OO实践。通过查看参数可以解决歧义。如果您被冒犯了,很抱歉。我认为对不同的参数/参数类型使用多态性确实是一种标准的OO实践,但只有当它们具有相同的含义时。这里的行为是不同的。
Integer idx = Integer.valueOf(2);
list.remove(idx)