集合与数组的区别,Collection、List、Set接口的作用及相关的之类
一、类集设置的目的(重点)
在Java中为了方便用户操作各个数据结构,所以引入了类集的概念,有时候就可以把类集称为Java对数据的实现。
类集中最大的几个操作接口:Collection、Map、Iterator,这三个接口为以后要使用的最重点的接口。
所有的类集操作的接口或类都在 java.util 包中。
Java类集结构图:
二、Collection 接口(重点)
Collection 接口是在整个 Java 类集中保存单值的最大操作父接口,里面每次操作的时候都只能保存一个对象的数据。
此接口定义在 java.util 包中。
此接口定义如下:
public interface Collection <E> extends Iterable<E>
此接口引用了泛型技术。
此接口的常用方法如下:
本接口中一共定义了 15 个方法,那么此接口的全部子类或子接口就将全部继承以上接口中的方法。
但是,在开发中不会直接使用 Collection 接口。而使用其操作的子接口:List、Set。
三、List接口(重点)
List是Collection的子接口,里面所有的内容都是可以重复的。
List子接口的定义:
public interface List<E>extends Collection<E>
此接口上依然使用了泛型技术。此接口对于 Collection 接口来讲有如下的扩充方法:使用List接口,需要找到该接口的实现类,常用的实现类有如下几个:
ArrayList、Vector、LinkedList
1、ArrayList
ArrayList 是 List 接口的子类,此类的定义如下:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
此类继承了 AbstractList 类。AbstractList 是 List 接口的子类。AbstractList 是个抽象类,适配器设计模式。
举例子:增加及获得元素
package org.listdemo.arraylistdemo;
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo01 {
public static void main(String[] args) {
List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型
all.add("hello "); // 增加内容,此方法从Collection接口继承而来
all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的
all.add("world"); // 增加内容,此方法从Collection接口继承而来
System.out.println(all); // 打印all对象调用toString()方法
}
}
以上的操作向集合中增加了三个元素,其中在指定位置增加的操作是 List 接口单独定义的。随后进行输出的时候,
实际上调用的是 toString()方法完成输出的。
可以发现,此时的对象数组并没有长度的限制,长度可以任意长,只要是内存够大就行。
2、Vector
与 ArrayList 一样,Vector 本身也属于 List 接口的子类,此类的定义如下:
public class Vector<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
此类与 ArrayList 类一样,都是 AbstractList 的子类。所以,此时的操作只要是 List 接口的子类就都按照 List 进行操作。
3、Vector 类和 ArrayList 类的区别
这两个类虽然都是List接口的子类,但是使用下来有如下区别:
4、链表操作类:LinkedList
此类使用概率较低,定义如下:
public class LinkedList<E> extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
此类继承了 AbstractList,所以是 List 的子类。但是此类也是 Queue 接口的子类,Queue 接口定义了如下的方法:
四、Set接口
Set 接口也是 Collection 的子接口,与 List 接口最大的不同在于,Set 接口里面的内容是不允许重复的。
Set 接口并没有对 Collection 接口进行扩充,基本上还是与 Collection 接口保持一致。因为此接口没有 List 接口中定义
的 get(int index)方法,所以无法使用循环进行输出。
那么在此接口中有两个常用的子类:HashSet、TreeSet
1、散列存放:HashSet
HashSet属于散列的存放类型,里面的内容是无序排放的。
通过循环的方式,由泛型所指定的类型变为指定的数组,将Set接口中的内容输出:
使用 T[ ] toArray(T[ ] a)
package org.listdemo.hashsetdemo;
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo03 {
public static void main(String[] args) {
Set<String> all = new HashSet<String>(); // 实例化Set接口对象
all.add("A");
all.add("B");
all.add("C");
all.add("D");
all.add("E");
String[] str = all.toArray(new String[] {});// 变为指定的泛型类型数组
for (int x = 0; x < str.length; x++) {
System.out.print(str[x] + "、");
}
}
}
2、排序的子类:TreeSet
与 HashSet 不同的是,TreeSet 本身属于排序的子类,此类的定义如下:
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
下面通过代码来观察其是如何进行排序的:
package org.listdemo.treesetdemo01;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo01 {
public static void main(String[] args) {
Set<String> all = new TreeSet<String>(); // 实例化Set接口对象\
all.add("D");
all.add("X");
all.add("A");
System.out.println(all);
}
}
虽然在增加元素的时候属于无序的操作,但是增加之后却可以为用户进行排序功能的实现。
小结:关于 TreeSet 的排序实现,如果是集合中对象是自定义的或者说其他系统定义的类没有实现Comparable 接口,则不能实现 TreeSet 的排序,会报类型转换(转向 Comparable 接口)错误。
换句话说要添加到 TreeSet 集合中的对象的类型必须实现了 Comparable 接口。
不过 TreeSet 的集合因为借用了 Comparable 接口,同时可以去除重复值,而 HashSet 虽然是Set 接口子类,但是对于没有复写 Object 的 equals 和 hashCode 方法的对象,加入了 HashSet集合中也是不能去掉重复值的。