1. 数组与集合
用来存储一种数据类型的集合容器。
特点:
1. 只能存储一种数据类型的数据
2. 一旦初始化,数组的长度是固定的
3. 数组中元素之间的内存地址连续
4. Object类型的数组可以存放任意类型的数据
集合相比与数组:
集合可以存放任意类型的数据对象,数组只能存放同一种类型的数据。
集合的长度是可以改变的,数组是固定长度的。
2. Collection接口
以下是Java API中关于Collection接口的说明:
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List)实现。归纳如下:
---| Collection 单例集合根接口
------| List 特点:有序、可以重复
------| Set 特点:无序、不可重复
Collection根接口的常见方法包括:增加元素、删除元素、查询、迭代等操作
package com.xpeng_V.collection;
import java.util.*;
/**
---| Collection 单例集合根接口
------| List 特点:有序、可以重复
------| Set 特点:无序、不可重复
*/
public class MyCollection{
public static void main(String[] args) {
//使用Collection的实现类ArrayList
Collection list = new ArrayList();
Collection list2 = new ArrayList();
/* 增加
* add(E e) 向集合中添加元素
* add(Collection<?> c) 向集合中添加一个集合
*/
System.out.println("=====================添加元素=====================");
list.add("xpeng_V");
list2.add("A");
list2.add("A");
list2.add(10);
list.add(list2);
System.out.println(list);
/* 删除
* remove() 删除集合中的指定元素(遇到的第一个)
* removeAll(Collection<?> c) 删除交集元素
* retainAll(collection<?> c) 保留交集元素,删除其他元素
* clear() 清空集合中的元素
*
*/
System.out.println("=====================删除元素=====================");
list2.remove("A");
list2.clear();
System.out.println(list2);
/* 查询
* size() 查看集合的大小
*/
System.out.println("=======================查询======================");
System.out.println("list="+list+"的大小是:"+list.size());
/* 判断
* isEmpty() 是否为空集合
* contains() 判断是否存在指定元素
* containsAll(Collection<?> c)
*/
System.out.println("=======================判断======================");
System.out.println("list是否为空:"+list.isEmpty());
System.out.println("是否存在xpeng_V:"+list.contains("xpeng_V"));
/* 迭代遍历
* toArray() 返回集合中的所有元素的为Object类型的数组
* iterator() 使用iterator迭代器遍历集合
*/
System.out.println("=====================迭代遍历=====================");
list.clear();
list.add(new Person(1, "甲"));
list.add(new Person(2, "乙"));
list.add(new Person(3, "丙"));
Object[] arr = list.toArray();
System.out.println("返回的数组是:"+Arrays.toString(arr));
//输出编号是2的人的信息
for (int i = 0; i < arr.length; i++) {
Person p = (Person) arr[i]; //返回数组类型是Object,需要强转
if(p.id == 2){
System.out.println(p);
}
}
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
class Person{
int id;
String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "{"+id+"--"+name+"}";
}
}
2.1 List接口
已经说明了Collection接口中常见的方法,以下代码包含List接口中特有的方法。
List接口中的特殊方法,都具有索引值。
package com.xpeng_V.collection;
import java.util.*;
/**
---| Collection 单例集合根接口
------| List 特点:有序、可以重复
------| Set 特点:无序、不可重复
*/
public class MyList {
public static void main(String[] args) {
List list = new ArrayList();
List list2 = new ArrayList();
System.out.println("有序、可重复、可以为空");
list.add("A");
list.add("A");
list.add("B");
list.add(null);
System.out.println(list);
list.clear();
/* 添加元素
* add(index i,E e) 将元素添加到集合的指定位置
* addAll(index i,Collection<?> c) 将集合c添加到原集合的指定位置
*/
System.out.println("====================添加元素====================");
list.add(1);
list.add(2);
list.add(3);
list.add(1, "e");
list2.add("4");
list2.add("5");
list.add(0, list2);
list.add(1);
System.out.println(list);
/* 获取方法
* get(index i) 获取指定索引值的元素
* indexOf(E e) 获取指定元素第一次出现在集合中的索引值
* lastIndexOf(E e) 获取指定元素最后一次出现在集合中的索引值
* subList(fromIndex i1,toIndex i2) 截取两索引值之间的元素返回一个List(包头不包尾)
*/
System.out.println("=====================获取=====================");
System.out.println("使用循环遍历List集合");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));
}
System.out.println();
System.out.println("元素'1'第一次出现的索引值:"+list.indexOf(1));
System.out.println("元素'1'最后一次出现的索引值:"+list.lastIndexOf(1));
List list3 = list.subList(2, 4);
System.out.println("返回的list:"+list3);
/* 修改
* set(index i,E e) 使用指定元素替换索引为i的元素
*/
System.out.println("=====================修改=====================");
list.set(0, "替换");
System.out.println(list);
/* 迭代
* listIterator()
*/
System.out.println("====================迭代遍历====================");
ListIterator it = list.listIterator();
/* ListIterator是Iterator的子接口,它具有Iterator的所有方法。
* add(E e) 把当前元素插入到当前指针所在的位置
* set(E e) 替换迭代器最后一次返回的元素
* hasPrevious() 逆序遍历
* previous() 返回前一个元素
*/
//逆序排列
while(it.hasNext()){
it.next(); //现将指针移动到列表最下端
}
while(it.hasPrevious()){
System.out.println(it.previous());//逆序遍历
}
it.next();
it.add("A");
System.out.println(list);
it.next();
it.next();
it.set("B");
System.out.println(list);
}
}
2.1.1 ArrayList
ArrayList底层维护了一个Object数组,使用无参构造函数实例化时,Object数组默认的容量是10,当容量不够时,自动增加0.5倍!
参考ArrayList源码:
---| Collection 单例集合根接口
------| List 特点:有序、可以重复
--------| ArrayList
--------| LinkedList
--------| Vector
------| Set 特点:无序、不可重复
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
private transient Object[] elementData;
private int size;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
//无参数构造方法,默认的容量是10
public ArrayList() {
this(10);
}
......
......
ArrayList特点:底层维护了一个Object数组,查询快,增删慢
ArrayList实例化时,会创建一个Object数组,内存地址是连续的,所以查询的速度快。
对ArrayList进行增加操作而ArrayList容量不足时,ArrayList首先会增加0.5倍的容量形成一个新的ArrayList,然后将以前的数据拷贝到新的ArrayList中,最后插入新增的数据。因为拷贝占用大量的时间,所以ArrayList增加的速度较慢;
对ArrayList进行删除操作时,会将删除元素之后的元素拷贝到前面的位置,所以删除的速度较慢;
2.1.2 LinkedList
LinkedList使用链表的数据结构实现,查询慢,增删快