是否有更有效的方法验证是否存在重复值(Java)?

是否有更有效的方法验证是否存在重复值(Java)?,java,Java,我需要验证给定ID的列表是否不包含任何重复值。我的尝试如下所示: public void validate(RecordCollection collection) throws BusinessException { LinkedHashMap<Long, Long> existingIds = new LinkedHashMap<Long, Long>(); for (Record record : collection.getAr

我需要验证给定ID的列表是否不包含任何重复值。我的尝试如下所示:

public void validate(RecordCollection collection)
        throws BusinessException {

    LinkedHashMap<Long, Long> existingIds = new LinkedHashMap<Long, Long>();

    for (Record record : collection.getArrayList()) {

        // check that you don't have two records with the same id
        if (existingIds.containsKey(record.getID())) {
            throw new BusinessException("records must be unique.",
                    ExceptionCodes.RECORDS_MUST_BE_UNIQUE);
        }

        //add the id to the map of existing ids
        existingIds.put(record.getID(), vo.getID());

    }
公共作废验证(RecordCollection)
抛出业务异常{
LinkedHashMap existingIds=新LinkedHashMap();
for(记录:collection.getArrayList()){
//检查您没有两个具有相同id的记录
if(existingIds.containsKey(record.getID())){
抛出新的BusinessException(“记录必须是唯一的。”,
例外代码。记录必须是唯一的);
}
//将该id添加到现有id的映射中
existingIds.put(record.getID(),vo.getID());
}

是否有更有效的方法来实施此验证?

是的,有,只需稍加修改:

for (Record record : collection.getArrayList())
    if (existingIds.put(record.getID(), vo.getID()) != null)
        throw new BusinessException("records must be unique.",
            ExceptionCodes.RECORDS_MUST_BE_UNIQUE);
Map
.put()
操作返回键的上一个值。如果没有条目,将返回
null
。在这里,由于您没有
null
值,这意味着如果返回码不是
null
,则您有一个副本

(另外,为什么要使用
LinkedHashMap
?您的方法返回
void
,因此插入顺序并不重要;只需使用
HashMap

(同样,正如建议的那样,在构建映射时,将其大小初始化为正在检查的集合的大小)

Set Set=new HashSet(collection.getArrayList());
System.out.println(x.size()==set.size());

若并没有重复,则打印true。在这种情况下,我会考虑一组id。 如果值已存在或不存在,add方法将返回布尔值

因此,您可以随时使用集合,如果add返回“false”,则抛出异常

关于实施: RecordCollection应该是一个集合并自己检查ID。因此验证方法是RecordCollection的私有部分,当添加元素时,如果需要,将引发异常。 完全避免了验证循环


如果无法将验证添加到集合中,则存在子类“IdenticalIDRecordCollection”

existingIds.containsKey(record.getID())
在我看来很好。
List List List=collection.getArrayList();Set=new HashSet(List);if(Set.size()
如果您的ID都在0和N之间,您还可以使用布尔数组进行固定时间查找。您还可以检查现有ID.put(record.getId(),vo.getId())的返回值。如果它不是
null
,您就有了一个重复项。@但这并不是快捷方式。我怀疑这两种方法之间是否会有显著的性能差异…@Thihara好吧,您只需对密钥执行一次单性检查,而不是LinkedHashMap v的两个优点—普通的HashMapI可以通过设置映射的初始容量以防止调整大小和重新灰化。实现详细信息:如果
ExceptionCodes
是枚举,则可以将消息和其中的代码捆绑在一起,甚至使其生成异常(类似于
throw ExceptionCodes.RECORDS必须是唯一的。asException())
)但这将吞掉arraylist中的所有条目。效率并不高…在我们找到第一个副本时,不必添加所有项目。但此代码确实会将所有项目添加到集合中-或者至少尝试将所有项目添加到集合中。是一个陷阱,尤其是
HashSet
:它在内部使用
HashMap
,至少在Sun的JDK中是这样的生成,然后进行验证。为什么?只需将其添加到集合中并检查是否有。一个步骤不需要额外的迭代。还有一个步骤:RecordCollection可以自己进行检查。其他地方没有验证。@fge确实有,但为什么这是一个陷阱?集合需要验证新条目不存在,并且是最快的O表示法的一种方式是使用散列。如果它基于一个简单的数组,它将需要迭代所有元素。还有
集合。newSetFromMap(Map Map)
允许使用任何
Map
来构建
集合
@zapl我指的是“效率”部分。虽然我怀疑在OP的情况下,这样的检查可以在其他地方以更有效的方式进行。。。
 Set set=new HashSet<>(collection.getArrayList());
 System.out.println(x.size()==set.size());