1.Set
Set集合是无序存放,即放入顺序和取出顺序不同
List存放数据是有序的,即放入顺序和取出顺序相同
1.HashSet
HashSet中存放的数据不能相同,但是不一个类型可以
HashSet set=new HashSet();
set.add(123);
set.add("123");
set.size();
set.add("123"); //Set中不能存储相同的数据
System.out.println(set); //123,123
int size=set.size(); //
System.out.println(size);
set.remove("123"); //现在只剩下int类型123
int size=set.size();
System.out.println(size); // 1 删除String类型123之后只剩下1个
面试题:
//面试题
//1.
set.add(new String("456")); //456存储的是Integer类型
set.add(new String("456"));
size=set.size();
System.out.println(size); // 3 就算是new了一个新对象在Set中存放的数也不能相同
//2.
set.add(null); //Set可以存null 而且Set长度会加1
size=set.size();
System.out.println(size); //4
2.TreeSet
TreeSet
treeSet.add(null);语法不报错,但是不能存 运行会报错:NullPointerException
TreeSet内部使用二叉树,内部节点是可以比较的,因为null不可以比较,不能确定将null放在哪个节点所以不能存null
同一个TreeSet对象中存储的内容应该是可以比较的 默认情况下不能存储不同类型
TreeSet treeSet=new TreeSet<>();
//存入数据
treeSet.add(2);
treeSet.add(200);
treeSet.add(3);
treeSet.add(88);
treeSet.add(45);
treeSet.add(72);
treeSet.add(1);
treeSet.add(59);
//先序遍历 中序遍历 后序遍历
for (Object item:treeSet){ //中序遍历
System.out.print(item+",");
}
TreeSet遍历的时候是中序遍历 而且输出的是一个正序的
3.LinkedHashSet
是一个有序的集合
4. 比较器
//比较器
Comparator<Student> comparator=(a,b)->{
if (a.score==b.score){
return 0;} //自己写一个比较器 大于的话输出1,小于输出-1,等于输出0
return a.score>b.score?1:-1;
};
TreeSet<Student> ttset=new TreeSet<>(comparator);//存入比较器
Student stua=new Student();
stua.score=99;
Student stub=new Student();
stub.score=89;
Student stuc=new Student();
stuc.score=100;
Student stud=new Student();
stud.score=9;
ttset.add(stua);
ttset.add(stub);
ttset.add(stuc);
ttset.add(stud);
for (Student item:ttset){
System.out.println(item.score); //输出的是正序的值
}
TreeSet tttset=new TreeSet<>(); //没存比较器,所以不能添加
Student stuaa=new Student();
stuaa.score=98;
tttset.add(stuaa);
stuaa=new Student();
stuaa.score=8;
tttset.add(stuaa);
stuaa=new Student();
stuaa.score=85;
tttset.add(stuaa);
for (Object it:tttset){
System.out.println(it); //输出的是对象地址
}
class Student implements Comparable{
int score;
@Override
public int compareTo(Object o) {
if (o instanceof Student){
Student item=(Student)o;
if (this.score==item.score)
{return 0;}
return this.score>item.score?1:-1;
}
else {
//o对象不是Student就无法比较 这是程序运行时出现的特殊情况
//这是异常 我们的方法处理不了这种情况 就要抛出一个异常对象
//告知调用此方法的代码
throw new RuntimeException("传入对象不可比较");
}
}
2.Map
Map中存储的是一对数据,是一对键值对,所以key值不能相同,只能有一个
线程安全的MAp Hashtable ConcurrentHashMap(锁的颗粒度比较小,性能优异)
1.HashMap
1.HashMap底层原理 数组加链表
2.数组默认容量是16 每次扩容扩两倍
3.扩容阈值 0.75 所以当map中数量到12就会扩容
4.如果一个链上的值超过8,就要对该链树华
5.一只树上的元素,低于6个,那么这个树就会退化成链
6.最小树化容量阈值 64(数组长度) 如果数组长度没有达到64,优先扩容
Map map =new HashMap();
map.put("A1","张三");
//可以通过存入的key获取存入的对象
map.get("A1"); //获取A1对应的对象
Object obj=map.get("A1");
System.out.println(obj); //张三
//通过key删除键值对
map.remove("A2");
System.out.println(map.remove("A2")); //如果没有这个key,返回null
System.out.println(map.remove("A1")); //删除之后返回删除的值
//是否包含key
System.out.println(map.containsKey("A1"));
//是否包含这个值
map.containsValue("张三");
//获取所有的key 返回的是set类型
Set setkey=map.keySet();
//获取所有的值 返回的是Collection集合
Collection con=map.values();
2.Tree Map
TreeMap的key应该是可以比较的而且不能是null ,但是value可以是null
3.LinkedHashMap
和LinkedHashMap基本相同 ,有序
4.HashTable
HashTable的key和value都不能是null
这是线程安全的,速度比较慢
5.ConcurrentHashMap
线程安全的但是效率快
3.泛型
泛型 就是广泛的类型
泛型 instance getclass都可以保证类型安全不会报错:ClassCastException
定义: 类或方法或属性上可以定义泛型
在类和方法上定义泛型:
public <E> E test(E e){
//返回的类型和传入的类型是一种
return e; //e就是E类型的
}
public void test(E e,R r){}
在属性上定义泛型:
private E e;
for (Object item:list){
//在类型转换的时候 没有明确对象的数据类型,进行强制类型转换
//这时候会抛出ClassCastException(类型转换异常)
//这就是类型不安全
String str=(String)item;
System.out.println(str);
}
List<String> listA=new ArrayList<>();//后边的<>是传递,前面的才是检查的作用
listA.add("123");//泛型只在变异的时候起作用 运行时不起作用 这里有一个装箱的操作
Map<String,Object> map=new HashMap<>();
testA(new ArrayList<>());
List<A> list1=new ArrayList<>();
List<B> list2=new ArrayList<>();
List<C> list3=new ArrayList<>();
testAA(list1,new B());
}
public static <J extends List> J testA(J j){//参数类型必须是List的子类(定义下限)
return j;
}
//public static <A super ArrayList>void testA(A a){}
// 应该也可以定义下限(下面这个)
public static <A> void testAA(List<? super A>a,A p) {
//
// 方法实现...
}
//泛型传递:类向方法传递 父类向子类传递
static class A{}
static class B extends A {}
static class C extends B{}