List,Set集合
概述
如图:
List接口
List集合中允许出现重复的元素,所有元素都是以一种线性方式进行存储,可以通过索引来查找指定元素。特点就是存入元素有序,可重复。
ArrayList集合
ArrayList是List接口的实现类,ArrayList内部封装了一个长度可变的数组对象,如果存入元素超过数组的长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素。
常用方法:
实例:
public class Exception01 {
public static void main(String[] args) {
//创建ArrayList集合
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("张三");
arrayList.add("李四");
arrayList.add("王二");
arrayList.add("麻子");
System.out.println("数组长度为:" + arrayList.size());
System.out.println("数组最后一个元素是:" + arrayList.get(arrayList.size()-1));
//遍历集合中的元素
for(String list : arrayList){
System.out.println(list);
}
}
}
ArrayList第一个元素的起始索引是从0开始的,最后一个元素是size-1。在访问元素的是时候一定注意,元素索引不能超过size-1这个范围。否则会抛出下标越界异常IndexOutOfBoundsException。正是因为ArrayList底层封装的是一个可变数组,在增删指定位置的元素时,导致创建新的数组,效率比较低,因此不适合做大量的增删操作。但适合通过索查找问元素比较快。
LinkeList集合
LinkeList集合内部封装的是一个双向链表,链表中的每一个元素都使用引用的方式来记住它前一个元素和后一个元素,从而将所有的元素连接起来。当我们插入一个元素是,只需要改变元素的前后索引关系即可,删除也一样。正是这种特性,LinkeList集合对于元素的增删操作有很高的效率。
常用方法:
实例:
public class Exception02 {
public static void main(String[] args) {
LinkedList<Object> linkedList= new LinkedList<Object>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("C");
linkedList.add("D");
//循环遍历输出
for (Object list: linkedList){
System.out.println(list);
}
System.out.println("元素长度为:" + linkedList.size());
System.out.println("集合的第一个是:" + linkedList.getFirst());
System.out.println("集合的最后一个是:" + linkedList.getLast());
//在集合头部添加一个元素
linkedList.addFirst("F");
//在集合尾部添加一个元素
linkedList.addLast("L");
System.out.println("添加后集合的第一个是:" + linkedList.getFirst());
System.out.println("添加后集合的最后一个是:" + linkedList.getLast());
System.out.println("------------------------------------------");
//移除集合头部添加一个元素
linkedList.removeFirst();
//移除集合尾部添加一个元素
linkedList.removeLast();
System.out.println("移除后集合的第一个是:" + linkedList.getFirst());
System.out.println("移除后集合的最后一个是:" + linkedList.getLast());
//移除指定位置的元素
linkedList.remove(0);
System.out.println("移除指定位置后集合的第一个是:" + linkedList.getFirst());
}
}
Vector集合
Vector集合也是基于数组实现的跟ArrayList特别像,但它是线程安全的,效率低,现在使用的不多。
Set接口
Set接口中的元素无序,并且存入的元素不出现重复。Set接口主要有两个实现类,HashSet和TreeSet。HashSet是根据对象的哈希值来确定元素存在集合中的存储位置,因此具有良好的存取和查找的性能。TreeSet是以二叉树的方式来存储元素,它可以对集合中的元素进行排序。
HashSet集合
HashSet是Set接口的一个实现类,它所存在的元素不可重复并且元素都是无序的。当向HashSet集合中存入元素时,首先会调用对象的hashCode()方法来确定元素的存储位置,然后在调用对象的equals()来确保该位置没有重复的元素。
实例:
public class Exception03 {
public static void main(String[] args) {
HashSet hashSet = new HashSet();//创建hashset集合
hashSet.add("A");//存入元素
hashSet.add("B");
hashSet.add("C");
hashSet.add("A");
Iterator iterator = hashSet.iterator();//获得iterator对象
while (iterator.hasNext()){
//如果有元素通过迭代器next()获得元素
Object next = iterator.next();
System.out.println(next);
}
}
}
运行结果:
HashSet集合之所以不能存入相同的元素,是因为当我们通过add()方法添加元素时,首先会调用当前对象的hashCode()方法获得对象的哈希值,然后根据哈希值计算出一个存储位置。如果该位置上面没有元素,直接将元素存入。如果该位置上有元素,则会调用equals()方法让当前存入元素依次和位置上的元素进行比较,如果返回false就将该元素存入集合。如果返回true,说明有重复的元素,就将该元素舍弃。
TreeSet集合
TreeSet是Set接口的另一个实现类,它内部采用自平衡二叉树存储元素,这样的结构保证了存入该集合中的元素不会重复,并且可以对其排序。
实例:
public class Exception04 {
public static void main(String[] args) {
//创建TreeSet集合
TreeSet treeSet = new TreeSet();
treeSet.add(6);//添加四个元素
treeSet.add(9);
treeSet.add(5);
treeSet.add(7);
//通过迭代器遍历集合中的元素
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
运行结果:
结果显示存入TreeSet集合中的元素去重并且排序输出。之所以能够排序是因为在向TreeSet集合存入元素时,就会将该元素与其他元素进行比较,最后将他们插入有序的对象序列中。该集合在进行元素比较是都会调用compareTo()方法,该方法是在Comparable接口中定义的,因此想要对集合中的元素进行排序,就必须实现Comparable接口。JDK中大部分的类都实现Comparable接口,所以自动拥有compareTo()方法。如果自定义类想要排序就必须要实现Comparable接口。