特性:无序不可重复
底层是红黑树,会自动排序,意味着里面存储的必须是同 类型的元素对象
Set set = new TreeSet();
//添加 元素 不可重复
set.add("1");
set.add("1");
set.add("1");
set.add("1");
set.add("11");
set.add("111");
set.add("2");
set.add("a");
set.add("8");
set.add("A");
set.add("[");
System.out.println(set);
//删除元素,根据内容删除
set.remove("8");
//遍历
for (Object object : set) {
System.out.println(object);
结果:[1, 11, 111, 2, 8, A, [, a]
为什么TreeSet可以自动排序? 因为 要添加的数据都实现了
Comparable接口,比如 Integer String等 都实现了
如果我们添加的为自定义类型的对象,则需要让该类也实现
Comparable接口并实现compareTo方法
class User implements Comparable {
int age;
public User(int age) {
this.age=age;
}
@Override
public int compareTo(Object o) {
//this 是 要添加的元素
// o 是集合中的元素
if(o instanceof User) {
User oldUser = (User)o;
//返回0 说明 相等,则不添加
//返回大于0,说明要添加的元素,比集合中的大,往后放
//返回小于0,说明要添加的元素,比集合中的小,往前放
return this.age - oldUser.age;
}
return 0;
}
使用TreeSet保存的数字(Integer)类型,此时由于Integer
class ComparatorImpl implements Comparator {
@Override
public int compare(Object o1, Object o2) {
// o1 是要添加的元素
// o2 是集合中的元素
//返回0 说明相同
//返回大于0,往后放
//返回小于0,往前放
return (Integer)o2 - (Integer)o1;
}
如果添加的元素类,是我们写的,比如User,那么我们想要排序,
可以使用comparable来解决,这样还能保留comparator的扩展性
如果添加的元素类,不是我们写的,意味着我们没办法修改对应的源码,
就使用comparator来解决
散列表 又叫哈希表 , 数组中保存的是单向链表
hash算法 : 是一种安全的加密算法,可以把不定长数据改为定长数据,
并且不保证其唯一性
其中算法包括 : 直接寻址法,数字分析法,平方取中法,折叠法,随机数法,
除留余数法
map特性 : 无序,key不可重复,value可重复, 保存的是key和value键值对
Node : 1 key , 2 value , 3 next , 4 hash
添加过程 :
添加数据时(key,value) , 调用key的hashCode方法,生成hash值,
然后通过hash算法得到数组下标
如果该下标对应的空间中,没有数据,就创建一个Node对象,
把key和value封装进去,保存到对应的下标上
如果该下标对应的空间中有数据,则调用key的equals方法,
和空间中所有的数据进行比较
如果没有相同的,则创建一个Node对象,
保存在这个单向链表中的尾部
如果equals判断有相同的,则不添加对应的key,value值
替换原来的value
1.8开始,为了提高查询效率,对链表进行了优化,
如果数组对应的链表中的数据大于等于7(第八个),
会把链表转换为红黑树
当红黑树的个数小于6,则转换为链表
HashMap map = new HashMap();
//key不能重复,重复不添加
map.put("a", "a1");
map.put("b", "b1");
//根据key删除这个映射关系
map.remove("a");
//如果key是未有的key,则为添加,如果 key 是已有的key,则是修改
//修改的是value值,key不能修改
map.put("b", "b2");
//根据key获取value值
System.out.println("b");
//个数
map.size();
//是否包含某个key
map.containsKey("");
//是否包含某个value
map.containsValue("");
//是否为空(个数是否为0)
map.isEmpty();
//清空
map.clear();
//System.out.println(map);
//遍历相关,map不能直接遍历
map.put("a", "a1");
map.put("b", "b1");
//获取所有的value值
map.values();
//把map中所有的key保存到set中,并返回
Set set = map.keySet();
for (Object object : set) {
System.out.println(object + ":"+map.get(object));
}
//把key和value封装到entry中,然后保存在set中返回
Set entrys = map.entrySet();
for (Object object : entrys) {
Entry entry = (Entry) object;
System.out.println(entry.getKey()+":"+entry.getValue());
}
泛型 : 编译时进行类型检查
可以限制类型统一,并且在编译时进行类型校验,不符合条件的不能使用
现在集合中 是可以保存任意元素 , 加上泛型之后,
就只能保存某一种数据类型的元素
泛型 不能写基本类型
E : element的简写,一般代表元素,而集合中或者数组中的数据,
我们叫元素
K V : 表示的是键值对,一般在map中存储
N : Number
T : type,表示具体的一个java类型
? : 表示不确定的类型
如果规定了泛型,但是不设置泛型的话,则默认为Object
//List<E>
//Map<K,V>
MyClass myclass = new MyClass();
myclass.m1(1);
myclass.m1("a");
}
}
class MyClass<T>{
public void m1(T t) {
System.out.println(t);
}