set集合
set无序(指插入和取出顺序不同),不可重复
treeset(底层由treemap):底层实现红黑树,实现添加数据时,添加的数据类型必须实现Comparable接口并且重写了compareTo方法,用于在treeset中存放数据进行比较添加位置。
比较器:Comparable,Comparator(需要重写比较规则时使用此匿名内部类)
public class Collection08 {
public static void main(String[] args) {
TreeMap map = new TreeMap();
Hashtable
// TreeMap中添加的key必须是可以排序的
// 要么添加的key实现了comparable接口 要么创建TreeMap的时候,传入comparator比较器
map.put(2, 4);
// 必须保存的是同类型的数据,因为不同类型没有可比性
// map.put("a",4);
map.put(2, 1);
map.put(12, 21);
map.put(3, 6);
System.out.println(map);
// String 是按照每位的ASCII码进行比较
map = new TreeMap();
map.put("a", 1);
map.put("t", 1);
map.put("f", 1);
map.put("b", 1);
// 注意 {1=1, 15=1, 2=1, 4=1, 6=1, 9=1}
// 2 > 1999999 因为先比较第一位ASCII码,相同再比较第二位
// 但是在比较第一位的时候 2 > 1 所以 2 > 19999999
map = new TreeMap();
map.put("1", 1);
map.put("2", 1);
map.put("9", 1);
map.put("4", 1);
map.put("15", 1);
map.put("6", 1);
map.put("a", 1);
System.out.println(map);
// 以下程序默认按照ASCII码排序,需求:使他们按照数值大小排序 1 2 4 6 9 15
map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// o1 是要添加的元素
// o2 是集合中的元素
String s1 = (String) o1;
String s2 = (String) o2;
// 转换为数值型
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
return i1 - i2;
}
});
map.put("1", 1);
map.put("2", 1);
map.put("9", 1);
map.put("4", 1);
map.put("15", 1);
map.put("6", 1);
System.out.println(map);
}
}
hashset(底层由hashmap):底层实现为散列表,由数组加单项链表组成,数组为16(加载因子为0.75当内容存到16*0.75=12个数据时,这数组进行扩容,扩容为16*2=32,链表默认值为8,当链表数据达到64时会转变为红黑树)
public class Collection0 {
public static void main(String[] args) {
HashMap hashMap = new HashMap<>();
hashMap.put(1, "h");
hashMap.put(2, "e");
hashMap.put(3, "l");
hashMap.put(4, "l");
hashMap.put(5, "o");
hashMap.put(6, "o");
hashMap.remove(6);
// System.out.println(hashMap);
// hashMap.forEach((key, value) -> System.out.println(key + ":" + value));
// hashMap.values().forEach(System.out::print);
// System.out.println();
// hashMap.keySet().forEach(System.out::print);
Set set = hashMap.entrySet();
for (Object s : set) {
// if (s instanceof Map.Entry)
Map.Entry ss = (Map.Entry) s;
System.out.println(ss.getKey());
}
HashMap map = new HashMap();
// 尾部添加
map.put(new Test(18, "张三"), 21);
// 存在后,key不添加,value值替换
map.put(new Test(20, "张三"), 56);
map.put(new Test(20, "张三2"), 56);
map.put("a", 56);
map.put("b", 56);
// 根据key 删除映射关系
map.remove(new Test(20, "张三2"));
// 根据key 查询value
System.out.println(map.get("a"));
// 修改 : key不能修改,只能修改value
// 和添加一样,如果是已有的key则为修改value值
// 如果是不存在的key则为添加映射关系
map.put("a", 66);
// 个数
System.out.println(map.size());
// 判断是否为空(个数是否为0)
map.isEmpty();
// 是否包含某个key
map.containsKey("");
// 是否包含某个value
map.containsValue("");
System.out.println(map);
// 获取map中所有的value,并保存在集合中返回
Collection values = map.values();
for (Object object : values) {
System.out.println(object);
}
// 获取map中所有的key,并保存在集合中返回
Collection keys = map.keySet();
for (Object object : keys) {
System.out.println(object + " ==> " + map.get(object));
}
// 把map中的key和value封装到entry对象中,并保存在集合中返回
Set entrys = map.entrySet();
for (Object object : entrys) {
Map.Entry entry = (Map.Entry) object;
System.out.println(entry.getKey()+" --> "+entry.getValue());
}
}
}
class Test {
@Override
public String toString() {
return name + ":" + age;
}
int age;
String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Test other = (Test) obj;
if (name == null) {
if (other.name != null) return false;
} else if (!name.equals(other.name)) return false;
return true;
}
public Test(int age, String name) {
super();
this.age = age;
this.name = name;
}
}
hashset添加规则:添加是K-V映射关系,用K调用hashCode()生成hash值,然后对这个值进行hash算法hash,得到对应的下标 用K调用hashCode()生成哈希值,然后对这个值进行哈希算法哈希,得到对应的下标;判断下标对应的数组中是否有数据,如果没有,就保存这个映射关系(K-V)即可;如果有数据,那么就调用K的equals方法,和数组中对应下标的所有数据进行比较,如果equals进行判断时,有相同的,就不添加此映射关系,新的value值替换原来的value值 ;如果没有相同的,就把该映射关系,添加到数组对应的链表中的尾部。