集合
List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
Set下有HashSet,LinkedHashSet,TreeSet List下有ArrayList,Vector,LinkedList
Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
Collection接口下还有个Queue接口,有PriorityQueue类
list集合:
ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点:
底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点:
线程不安全,效率高
vector真的安全吗?
Set 无序,唯一
HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals()LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一TreeSet
底层数据结构是红黑树。(唯一,有序)
- 如何保证元素排序的呢? 自然排序 比较器排序
2.如何保证元素唯一性的呢? 根据比较的返回值是否是0来决定
Map:
Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。
TreeMap是有序的,HashMap和HashTable是无序的。
Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。 这就意味着:Hashtable是线程安全的,HashMap不是线程安全的。 HashMap效率较高,Hashtable效率较低。
如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。
查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有
synchronized关键字,而HashMap的源码中则没有。
Hashtable不允许null值,HashMap允许null值(key和value都允许)
父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap
小插曲:
1.类中要是存在有参构造方法,那就一定要写无参构造。
2.父类如果只有无参,那子类可以不写super,否则必须写
TreeSet的自然排序与比较器排序
1.自然排序:
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Student s) {
//return -1; //-1表示放在红黑树的左边,即逆序输出
//return 1; //1表示放在红黑树的右边,即顺序输出
//return o; //表示元素相同,仅存放第一个元素
//主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
int num=this.name.length()-s.name.length();
//姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
//如果这两个字符串相等,则结果为 0
int num1=num==0?this.name.compareTo(s.name):num;
//姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄
int num2=num1==0?this.age-s.age:num1;
return num2;
}
}
ps:三目运算符:num如果是0 执行?右边第一个赋值给num1
2.比较器排序:
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student s1,Student s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// 年龄
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
}
public class MyClass {
public static void main(String[] args) {
//创建集合对象
//TreeSet(Comparator<? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());
//创建元素对象
Student s1=new Student("zhangsan",20);
Student s2=new Student("lis",22);
Student s3=new Student("wangwu",24);
Student s4=new Student("chenliu",26);
Student s5=new Student("zhangsan",22);
Student s6=new Student("qianqi",24);
//将元素对象添加到集合对象中
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
//遍历
for(Student s:ts){
System.out.println(s.getName()+"-----------"+s.getAge());
}
}
}
Arraylist的用法:
补充:
Arrays类的用法:
1.fill填充函数
int [] arr=new int[5];
Arrays.fill(arr,5);
System.out.println(arr);
String str=Arrays.toString(arr);
System.out.println(str);
int[] arr = new int[5];//新建一个大小为5的数组
Arrays.fill(arr, 2,4,6);//给第2位(0开始)到第4位(不包括)赋值6
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[0, 0, 6, 6, 0]
2.equals函数
int[] arr1 = {1,2,3};
int[] arr2 = {1,2,3};
System.out.println(Arrays.equals(arr1,arr2));
//输出:true
//如果是arr1.equals(arr2),则返回false,因为equals比较的是两个对象的地址,不是里面的数,而Arrays.equals重写了equals,所以,这里能比较元素是否相等
3.查找
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,30));
//输出:2 (从0到3位(不包括)找30,找到了,在第2位,返回2)
4.重点Arrays.sort函数用到了比较器