知识点:
类集的主要作用
2、 Collection、List、Set 接口的作用及相关的子类
3、 Map 的作用及相关的子类
4、 Object 类的作用
5、 掌握泛型在整个 Java 类集的作用
6、 Collections 工具类
7、 equals、hashCode 与内存泄露分析
Collection 接口
- List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
- Set下有HashSet,LinkedHashSet,TreeSet
- List下有ArrayList,Vector,LinkedList
- Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
- Collection接口下还有个Queue接口,有PriorityQueue类
注意:
-
Queue接口与List、Set同一级别,都是继承了Collection接口。
看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。 -
SortedSet是个接口,它里面的(只有TreeSet这一个实现可用)中的元素一定是有序的。
Connection接口:
— List 有序,可重复
- ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高 - Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低 - LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高
—Set 无序,唯一
-
HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
1.依赖两个方法:hashCode()和equals() -
LinkedHashSet
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一 -
TreeSet
底层数据结构是红黑树。(唯一,有序)
1. 如何保证元素排序的呢?
自然排序
比较器排序
新的子类:ArrayList
增加及取得元素
List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型
all.add("hello "); // 增加内容,此方法从Collection接口继承而来
all.add(0, "VINCE ");// 增加内容,此方法是List接口单独定义的
all.add("world"); // 增加内容,此方法从Collection接口继承而来
System.out.println(all); // 打印all对象调用toString()方法
注:以上的操作向集合中增加了三个元素,其中在指定位置增加的操作是 List 接口单独定义的。随后进行输出的时候,
实际上调用的是 toString()方法完成输出的。
可以发现,此时的对象数组并没有长度的限制,长度可以任意长,只要是内存够大就行。
使用 remove()方法删除若干个元素,并且使用循环的方式输出。
List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型
all.add("hello "); // 增加内容,此方法从Collection接口继承而来
all.add(0, "VINCE ");// 增加内容,此方法是List接口单独定义的
all.add("world"); // 增加内容,此方法从Collection接口继承而来
all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的
all.remove("world");// 删除指定的对象
System.out.print("集合中的内容是:");
for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来
System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的
旧的子类:Vector
此类与 ArrayList 类一样,都是 AbstractList 的子类。所以,此时的操作只要是 List 接口的子类就都按照 List 进行操作
List<String> all = new Vector<String>(); // 实例化List对象,并指定泛型类型
all.add("hello "); // 增加内容,此方法从Collection接口继承而来
all.add(0, "VINCE ");// 增加内容,此方法是List接口单独定义的
all.add("world"); // 增加内容,此方法从Collection接口继承而来
all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的
all.remove("world");// 删除指定的对象
System.out.print("集合中的内容是:");
for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来
System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的
Set 接口
散列存放:HashSet
既然 Set 接口并没有扩充任何的 Collection 接口中的内容,所以使用的方法全部都是 Collection 接口定义而来的。
HashSet 属于散列的存放类集,里面的内容是无序存放的。
Set<String> all = new HashSet<String>(); // 实例化Set接口对象
all.add("A");
all.add("B");
all.add("C");
all.add("D");
all.add("E");
System.out.println(all);
使用 HashSet 实例化的 Set 接口实例,本身属于无序的存放。
Set<String> all = new HashSet<String>(); // 实例化Set接口对象
all.add("A");
all.add("B");
all.add("C");
all.add("D");
all.add("E");
Object obj[] = all.toArray(); // 将集合变为对象数组
for (int x = 0; x < obj.length; x++) {
System.out.print(obj[x] + "、");
上的操作不好,因为在操作的时候已经指定了操作的泛型类型,那么现在最好的做法是由泛型所指定的类
型变为指定的数组。
String[] str = all.toArray(new String[] {});// 变为指定的泛型类型数组
Set 接口中是不能有重复的内容的。
排序的子类:TreeSet
与 HashSet 不同的是,TreeSet 本身属于排序的子类
Set<String> all = new TreeSet<String>(); // 实例化Set接口对象\
all.add("D");
all.add("X");
all.add("A");
System.out.println(all);
排序的说明
定义 Person 类
public class Person
private String name;
private int age;
向里面增加若干个 Person 对象。
Set<Person> all = new TreeSet<Person>();
all.add(new Person("张三", 10));
all.add(new Person("李四", 10));
all.add(new Person("王五", 11));
all.add(new Person("赵六", 12));
all.add(new Person("孙七", 13));
System.out.println(all);
发现出现了如下的错误提示:
Exception in thread "main" java.lang.ClassCastException:
org.vince.listdemo.treesetdemo02.Person cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at
org.vince.listdemo.treesetdemo02.TreeSetPersonDemo01.main(TreeSetPersonDemo01.java:11)
此时的提示是:Person 类不能向 Comparable 接口转型的问题?
所以,证明,如果现在要是想进行排序的话,则必须在 Person 类中实现 Comparable 接口。
public class Person implements Comparable<Person> {
private String name;
private int age;
小结:
关于 TreeSet 的排序实现,如果是集合中对象是自定义的或者说其他系统定义的类没有实现
Comparable 接口,则不能实现 TreeSet 的排序,会报类型转换(转向 Comparable 接口)错误。
换句话说要添加到 TreeSet 集合中的对象的类型必须实现了 Comparable 接口。
不过 TreeSet 的集合因为借用了 Comparable 接口,同时可以去除重复值,而 HashSet 虽然是
Set 接口子类,但是对于没有复写 Object 的 equals 和 hashCode 方法的对象,加入了 HashSet
集合中也是不能去掉重复值的。
集合输出
Iterator 属于迭代输出,基本的操作原理:是不断的判断是否有下一个元素,有的话,则直接输出。
Collection<String> all = new ArrayList<String>();
all.add("A");
all.add("B");
all.add("C");
all.add("D");
all.add("E");
Iterator<String> iter = all.iterator();
while (iter.hasNext()) {// 判断是否有下一个元素
String str = iter.next(); // 取出当前元素
System.out.print(str + "、");