为什么这个HashSet代码片段会以这种方式运行?

时间:2017-03-29 20:56:32

标签: java hashset

给出以下代码:

public class NewClass {

    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("Orange", "Pineapple", "Banana", "Banana");
        Set<String> fruitsSet = new HashSet<>();

        for (String fruit : fruits) {
            fruitsSet.add(fruit);
        }

        for (String fruit : fruitsSet) {
            System.out.println(fruit);
        }
    }
}

每次运行代码时,元素的顺序都是相同的,消除了重复项Banana,这是典型的HashSet实现:

Banana
Pineapple
Orange

我的问题是,为什么订单每次都相同,因为规范说&#34;它不能保证集合的迭代顺序&#34; (https://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html

3 个答案:

答案 0 :(得分:5)

“无保证”仅仅意味着:没有保证。它可能正是每次将元素插入集合的顺序。它可以是随机顺序。除了星期二满月之外,它可以在任何时候完全相同。 “不保证”并不意味着“随机”或“不可预测”,它只是意味着您不能依赖任何特定的订单,因为它可能因任何原因而改变。

答案 1 :(得分:0)

HashSet存储元素的顺序取决于每个元素的hashCode。因为每次您放置相同的String时,hashCode的{​​{1}}也相同且订单也相同。

但正如 Louis Wasserman 所说,你不应该依赖那个订单,因为不能保证它不会在新的JDK中被改变。

答案 2 :(得分:0)

散列集中的迭代顺序由散列函数转换每个元素以创建其hashCode的方式决定。 因此,对于特定的字符串,您将获得特定的hashCode,并且他将被放置在Set的特定单元格中。

无保证意味着在迭代时添加Orange,Pineapple和Banana不能保证订单。

此外,它通过不承诺某些限制(例如排序)为HashSet的未来实现留出空间。