当前位置: 首页 > 知识库问答 >
问题:

我喜欢收藏家。toSet()是否总是返回哈希集?合同是什么?

鄂昌胤
2023-03-14

Javadoc说

返回一个收集器,该收集器将输入元素累加到一个新集合中。无法保证返回的集合的类型、可变性、可序列化性或线程安全性;如果需要对返回集进行更多控制,请使用toCollection(java.util.function.Supplier)。

所以Collectors。toCollection(HashSet::new)似乎是一个避免出现问题的好主意。

我的问题是,尽管我尽了最大努力,我还是无法从toSet()中得到比HashSet

下面是我使用的代码:

public static void main(String[] args) {
    List<Integer> l = Arrays.asList(1,2,3);

    for (int i = 0 ; i++<1_000_000;){
        Class clazz = l.stream().collect(Collectors.toSet()).getClass();

        if (!clazz.equals(HashSet.class)) {
            System.out.println("Not a HashSet");
        }
    }
}

那么,为什么Javadoc声明没有保证,而事实上,有...

共有3个答案

吉和同
2023-03-14

Collectors::toSet返回Set类型是一个实现细节。在未来的版本中,您不应该依赖于实现细节来保持不变。现在,他们使用的是哈希集,但将来他们可能会想使用另一种类型的哈希集。

卫振
2023-03-14

当前OpenJDK的实现(以及AFAIK和Oracle的实现)确实总是返回一个HashSet-但是不能保证这一点。如果您以某种方式假设Collectors.toSet()将返回一个HashSet(例如,显式地向下转换它),那么JDK的未来版本很可能会改变这种行为并破坏您的代码。

狄冠宇
2023-03-14

JavaDoc声明没有保证,但这并不妨碍任何特定的实现始终返回特定类型的集合。这只是设计师们说他们不想限制未来的实现。它没有说明当前实现的实际功能

换句话说,您已经发现了实现定义的行为(总是返回一个HashSet),但如果您指望这一点,将来可能会遇到问题。

 类似资料:
  • 以下面这行代码为例: 我想要一个。用一个调试器来调试代码,我确实得到了一个。我看了一下来观察下面的代码: 合同保证了一个,实现决定了一个;似乎是合理的。但是,我的实现需要一个保证的恒定时间查找,而不仅仅是任何旧的。如果的实现决定使用一个,这完全在它的权利范围内,我的实现就受到了损害。 这个问题的最佳解决方案是什么?

  • 问题内容: 我不是在谈论String类或哈希码被覆盖的任何其他类。假设如果我只是创建该类的新对象,那么在任何情况下the或true 都将返回该对象的内存地址? 问题答案: 不必要。从文档(重点是我的): 在合理可行的范围内,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。(通常通过将对象的内部地址转换为整数来 实现 , 但是JavaTM编程语言不需要这种实现技术 。)

  • 从原理到应用分析什么是哈希? 一、什么是哈希? 哈希(hash):将任意长度的输入(关键字),通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值,通常哈希值代表了关键字的存储位置。 但是为什么要这样做呢?或者说,哈希是怎样来的呢? 哈希的出现解决了两个问题:存储和搜索。 1. 存储(数据结构):如果在容器中保存对象及其关联的键,并且不用键

  • 问题内容: 如果我运行查询,例如: 即使查询与任何记录都不匹配,它也会始终返回结果吗?还是我需要验证并确保结果返回一行? 问题答案: 是的,因为它是一个聚合并且返回零。除非您添加GROUP BY,否则由于没有组,因此没有结果… 除非您添加GROUP BY,然后没有任何行,否则MAX / SUM等将返回NULL。只有COUNT传回没有结果的数字 编辑,有点晚:SUM会像MAX一样返回NULL 编辑,

  • 问题内容: 有人告诉我,InnoDB比MyISAM好得多。因此,当我创建表时,是否应该 始终 尝试使用InnoDB Engine而不是MyISAM?还是两者都有很大的好处? 问题答案: 是无事务的并且是堆组织的。记录由表中的行偏移量标识,索引将此偏移量存储为行指针。 支持交易并按索引组织。记录由的值标识(或未定义隐藏的内部列),并存储在中。二级索引将的值存储为行指针。 涉及全表扫描或二级索引查找的

  • 假设我有一个方法将只读视图返回到成员列表中: 进一步假设客户机所做的只是立即对列表进行一次迭代。也许是为了把玩家放进一个JList或者别的什么。客户端没有存储对列表的引用以供以后检查! 对于这种常见的场景,我是否应该返回一个流呢? 还是返回流在Java中不是惯用的?流被设计成总是在创建它们的同一个表达式中“终止”吗?