集合
存放数据类型的容器,可以是引用类型
Collection接口下的
- List
- ArrayList
- 允许有重复的元素出现
- 有序的
- 是线程不安全的,运行效率高
- ArrayList
- Set
- HashSet
- 不允许有重复的元素
- 无序的
- hashset的set方法不保证迭代顺序,也不保证保存后的顺序是永恒不变的(比如你存了[a,b,c],1000年后可能就变成[a,c,b]了)
- 线程不安全,效率高
- 允许使用null,但是只能使用一个
- HashSet
hashSet是如何保证不会有重复的元素的呢?
- 首先看对象的hashCode值
- 如果hashCode不重复,直接存入
- 如果hashCode重复,则调用对象的equals方法
- 调用equals返回true或者false
- 如果返回true,不存入
- 如果返回false,挂载到相同hashCode的桶的下面
例子
HashSet<String> integers = new HashSet<String>();
integers.add("1");
integers.add("1");
integers.add("1");
System.out.println(integers);
首先看String的hashCode方法(如果是Integer就去找Integer的hashCode方法呗)
还有如果是integers.add("a"+1);
这种,会先去找String的hashCode方法,然后再去找Integer的hashCode方法,然后再把两个hashCode方法得到的值加起来
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
如果hashCode不重复,直接存入
integers.add("1");
重复了,所以去调用 equals
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
跟已经在集合中的"1"
比较(就是第一行存进去的那个"1"
),返回true,所以不放入…
HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。