Java学习笔记之集合框架1
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类,Java中常用集合关系如图1所示。容器也叫集合。
图1
一、Collection接口
1、描述:Collection接口是集合的顶层接口它有2个常用的子接口List和Set接口。集合只用于存储对象,长度可变,可存储不同类型的对象。
2、常用方法:
2.1添加功能:
boolean add(Ee) 把给定的数据添加到集合中,注意可以添加任何类型的数据,推荐只添加相同类型的元素。
booleanaddAll(Collection c) 把给定的集合的元素,添加到当前集合中
2.2删除功能:
voidclear()将集合中的元素清空
booleanremove(Object o)将给定的元素在集合中删除,删除成功返回true
booleanremoveAll(Collection c)将给定的集合元素,在当前集合中删除
2.3长度功能:
int size() 返回集合中元素的个数
注意:获取数组长度是数组名.length,获取String类型的长度是字符串对象名.length(),获取集合长度是集合对象名.size()。
2.4转换功能:
Object[]toArray()把集合转换成数组
2.5判断功能:
booleancontains(Object o)判断当前集合中是否包含给定的元素
booleanisEmpty() 判断当前集合中的元素 是否为空
booleancontainsAll(Collection<?> c) 判断当前集合中是否包含给定集合中所有的元素
2.6遍历功能(迭代器):
Iterator<E>iterator(): 遍历集合中的元素
2.7交集功能:
booleanretainAll(Collection<?> c)判断两个集合中相同的元素
测试示例1:
public class CollectionDemo2{
public static void main(String[] args) {
//1创建集合对象,多态方式:父类引用指向子类对象
Collection<String>c = newArrayList<String>();
//2把给定的数据添加到集合中
c.add("hello");
c.add("Java");
c.add("Android");
c.add("JavaEE");
//打印添加元素后的集合
System.out.println("添加元素后的集合是:"+c);
//3、把集合转换成数组
Object[] objArray = c.toArray();
//4、用for循环遍历数组
System.out.print("用for循环遍历集合:");
for (inti = 0;i < objArray.length;i++) {
System.out.print(objArray[i] +" ");
}
System.out.println();//换行
//获取集合长度
int count = c.size();
System.out.println("集合的长度是:"+count);
//删除集合中一个元素
booleanflag =c.remove("hello");
//查看删除是否成功
System.out.println("hello元素是否删除成功:"+flag);
System.out.println("删除后的集合是:"+c);//打印删除后的集合
//判断当前集合中是否包含给定的元素。
booleanflag1 =c.contains("Java");
//打印判断结果
System.out.println("是否包含给定元素Java:"+flag1);
//将集合中的元素清空
c.clear();
System.out.println("清空后的集合是:"+c);//打印清空后的集合
//判断当前集合中的元素是否为空
booleanflag2 =c.isEmpty();
System.out.println("集合是否为空:"+flag2);//打印判断结果
}
}
结果为:
添加元素后的集合是:[hello,Java, Android, JavaEE]
用for循环遍历集合:hello Java Android JavaEE
集合的长度是:4
hello元素是否删除成功:true
删除后的集合是:[Java,Android, JavaEE]
是否包含给定元素Java:true
清空后的集合是:[]
集合是否为空:true
测试示例:
public class CollectionDemo3 {
public static void main(String[] args) {
//集合1
Collection<String> c1 =newArrayList<String>();
c1.add("hello1");
c1.add("hello2");
c1.add("hello3");
//集合2
Collection<String> c2 =new ArrayList<String>();
c2.add("world1");
c2.add("world2");
c2.add("world3");
c2.add("world4");
//把给定的集合的元素,添加到当前集合中
booleanflag =c1.addAll(c2);//把集合c2中的元素添加到集合c1中
System.out.println("元素是否添加成功:"+flag);
SOP(c1, c2);
//判断当前集合中,是否包含给定集合中所有的元素
booleanflag1 =c1.containsAll(c2);
System.out.println("是否包含所有元素:"+flag1);
SOP(c1, c2);
//判断两个集合中相同的元素,即2个集合的交集
booleanflag2 =c1.retainAll(c2);
System.out.println("2个集合是否有交集:"+flag2);
SOP(c1, c2);
//将给定的集合元素,在当前集合中删除
booleanflag3 =c1.removeAll(c2);
System.out.println("元素是否删除成功:"+flag3);
SOP(c1, c2);
}
public static void SOP(Object obj1, Object obj2){
System.out.println("c1:"+obj1);
System.out.println("c2:"+obj2);
}
}
结果为:
元素是否添加成功:true
c1:[hello1,hello2, hello3, world1, world2, world3, world4]
c2:[world1,world2, world3, world4]
是否包含所有元素:true
c1:[hello1,hello2, hello3, world1, world2, world3, world4]
c2:[world1,world2, world3, world4]
2个集合是否有交集:true
c1:[world1,world2, world3, world4]
c2:[world1,world2, world3, world4]
元素是否删除成功:true
c1:[]
c2:[world1, world2, world3, world4]
二、Iterator<E>接口
1、概述:用以方便的实现对容器内元素的遍历操作。
注意:如图1所示,所有实现Collection接口的集合类都有一个iterator() 方法用以返回一个实现了Iterator接口的对象。
2、成员方法
boolean hasNext()//如果仍有元素可以迭代,则返回true
E next()//返回迭代的下一个元素。
void remove()//从迭代器指向的collection中移除迭代器返回的最后一个元素(可选操作)。
next()方法的图解,如图2所示
图2
3、案例
public class CollectionDemo {
public static void main(String[] args) {
//1创建集合对象
Collection c = new ArrayList();//多态方式
//2把字符串对象添加到集合
c.add("javase");
c.add("javaee");
c.add("javaweb");
//3遍历迭代器对象,用来遍历当前集合
Iterator it = c.iterator();
//iterator()是Collection接口中的方法
//判断集合中是否有元素
while (it.hasNext()) {
System.out.println(it.next()+" ");//获取集合中的元素
}
}
}
结果为:javase javaee javaweb
综合测试:通过集合存储自定义对象(Person),并遍历(iterator迭代器遍历)
public class CollectionDemo2{
public static void main(String[] args) {
//1创建集合对象
Collection c = new ArrayList();
//2创建自定义元素对象
Person p1 = new Person("小明",8);
Person p2 = new Person("小强",18);
Person p3 = new Person("云云",28);
//3把自定义元素对象添加到集合
c.add(p1);
c.add(p2);
c.add(p3);
//4获取迭代器对象,遍历集合
Iterator it = c.iterator();//
//5用迭代器中的方法来判断是否有元素
while (it.hasNext()) {
//6获取元素并强转为Person类型。
Person p = (Person)it.next();
System.out.println(p.getName() +"--" +p.getAge());
}
}
}
//自定义类
public class Person {
private Stringname;
private int age;
public Person(Stringname,intage) {
super();
this.name =name;
this.age =age;
}
public String getName(){
return name;
}
public int getAge() {
return age;
}
}
输出结果:
小明--8
小强--18
云云--28
三、List接口
1、 描述:是Collection子集合,它里面存储的元素可以重复且有顺序(元素的存与取的顺序一致)
2、 特有方法
2.1添加功能
void add(int index, E element)//在当前集合中指定位置添加给定的元素
2.2删除功能
Eremove(int index)//移除集合中指定位置的元素
2.3获取功能
Object get(int index)//返回集合中指定位置的元素
int indexOf(E o)//获取给定的对象在集合中第一次出现的位置
2.4遍历功能
ListIterator<E>listIterator()//返回此集合元素的列表迭代器
2.5替换功能
E set(int index, E element)//用指定元素替换集合中指定位置的元素
2.6截取功能
ListsubList(int fromIndex,int toIndex)//从指定位置开始,到指定位置结束,截取该集合
注意:在遍历List集合时,不能对集合中的元素个数进行增加和删除的操作,否则会发生并发修改异常,但可以改变元素的内容。
3、 案例1
public class ListDemo {
public static void main(String[] args) {
//1创建List集合对象
List<String>list = new ArrayList<String>();
//2添加元素
list.add("hello0");//0
list.add("hello1");//1
list.add("hello2");//2
System.out.println("用add(E e)方法添加后的元素是:");
System.out.println(list);
list.add(1, "hello3");//在指定位置添加元素,原有元素后移
System.out.println("用add(int index, E element)方法添加后
的元素是:");
System.out.println(list);
Object obj = list.get(1);//返回集合中指定位置的元素
System.out.println("下标为1的元素是:"+obj);
//返回此集合中第一次出现的指定元素的索引,
//如果此列表不包含该元素,则返回 -1。
int index = list.indexOf("Hello3");
System.out.println("Hello3的下标:"+index);
int index1 = list.indexOf("hello3");
System.out.println("hello3的下标:"+index1);
//移除集合中指定位置的元素
Object obj2 = list.remove(1);//返回被删除的对象
System.out.println(obj2);//打印被删除的对象
System.out.println(list);//打印被删除后的元素
// set方法用指定元素替换集合中指定位置的元素
Object old = list.set(1, "world");
System.out.println("old:" +old);
System.out.println(list);
}
}
结果是:
用add(Ee)方法添加后的元素是:
[hello0,hello1, hello2]
用add(intindex, E element)方法添加后的元素是:
[hello0,hello3, hello1, hello2]
下标为1的元素是:hello3
Hello3的下标:-1
hello3的下标:1
hello3
[hello0,hello1, hello2]
old:hello1
[hello0, hello3333333, hello2]
案例2:用list集合存储字符串对象,并使用迭代器和普通for循环遍历
public class ListDemo2 {
public static void main(String[] args) {
//1创建List集合对象
List list = newArrayList();
//2把字符串元素添加到集合
list.add("青龙");
list.add("白虎");
list.add("朱雀");
list.add("玄武");
//3遍历
//方式1,迭代器方式,while结束时对象it任存在。
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("------");
//迭代器方式,for循环结束,it2也随之消失,
for (Iteratorit2 =list.iterator();it2.hasNext(); ) {
System.out.println(it2.next());
}
System.out.println("------");
//方式2普通for循环方式,使用List接口中的方法
for (inti = 0;i < list.size();i++) {
//每一个集合中的元素
Object obj = list.get(i);
System.out.println(obj);
}
}
}
4、 List接口中特有的listIterator方法和ListIterator接口中的方法
4.1、ListIteratorlistIterator()方法返回此集合元素的列表迭代器(按适当顺序)。在用listIterator()方法遍历List集合时可使用ListIterator接口中的方法对List集合中的元素进行增删改查排序等操。
4.2 ListIterator<E>接口中的常用方法
boolean
hasNext()
以正向遍历列表时,如果列表迭代器有多个元素则返回true
boolean
hasPrevious()
如果以逆向遍历列表,列表迭代器有多个元素,则返回true。
实例:
public class ListIteratorDemo{
public static void main(String[] args) {
//创建集合对象
List list = newArrayList();
//添加元素
list.add("java");
list.add("javaEE");
list.add("javaSE");
//遍历:正向遍历
ListIteratorlit = list.listIterator();
while (lit.hasNext()) {
System.out.println(lit.next());
}
System.out.println("-------------------");
//用for循环的方式反向遍历
for (inti=list.size()-1;i>=0;i--) {
System.out.println(list.get(i));
}
//用ListIterator迭代器反向遍历
System.out.println("-------------------");
while (lit.hasPrevious()) {//是否有上一个元素
//获取上一个元素
System.out.println(lit.previous() );
}
}
}
注意:在使用ListIterator迭代器中的方法反向遍历前,必须先正向遍历一次,才
能使用迭代器反向遍历,因为元素下标默认从0开始,当没有正向遍历就直接反向遍
历时,会出现取不到元素的现象,如图3所示。
图3
5、 常见数据结构
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。常见数据结构有:
栈,堆,递归,队列,数组,链表,哈希表,树,图等,以下为几种常用的数据结构。
栈:是一个操作受限的线性表,是一种可以实现先进后出的存储结构。
栈的操作:插入称为入栈,删除称为出栈。
栈的分类:静态栈(数组实现)和动态栈(链表实现)。
栈的模型类:似于一个杯子,它遵循先进后出,后进先出的原则,如图4所示。
栈的应用:函数调用,括号的匹配{([])},表达式求值等。
图4
队列:queue是一种先进先出(first infirst out:FIFO)的线性表,它只允 许在表的一端进行插入,另一端删除元素。
队列的分类:链式队列(用链表实现)和静态队列(用数组实现,必须是循环队列)
队列的模型:类似于现实生活中排队买票(不考虑插队的现象),只允许从队尾进入,从队头出队,不允许从队头和队尾之间的任何地方入队出队,如图5所示。
队列的应用:操作系统中的优先级队列,java中线程队列。
图5
数组:长度固定,一般存储同一类型的元素。
特点:存取速度快,插入删除慢,数组的长度扩展不灵活,且有长度限制。
注意:在java中可以定义Object类类型的数组,存储不同类型的元素,不过不建议这样使用,最好使用集合。
数组分类:一维数组,二维数组,多维数组。
链表:节点随机分配,通过指针相连,每个节点有一个前驱节点,每个节点有一个 后续节点。
链表分类:单链表,双链表,循环链表,非循环链表
链表的模型:类似于自行车的链条,只不过自行车的链条是有顺序的,而内存中的 链表的每个节点是随机的,如图6所示。
特点:插入删除元素快,存取元素速度慢,链表的长度“没有”限制。
图6单链表
树:Tree是n(n≥0)个结点的有限集。
树的特点:树中至少有一个根结点,树中各子树是互不相交的集合。
树的分类:一般树,二叉树(常用),森林。
树的模型:计算机中的“树”是一棵倒着的“树”,实际上更像一串“葡萄”,如图 7所示。
图7
四、ArrayList类(常用重点)
1、描述: ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变 数组的长度。
特点:长度可变,可以灵活的插入删除元素,和普通的数组相比操作速速稍慢。
2、常用方法
ArrayList类中的常用方法几乎都是实现List接口或Collection接口中的常用方法。ArrayList类中的方法的用法和List、Collection接口中的方法用法一致。
2.1增加功能
boolean
add(
E e)
将指定的元素添加到此列表的尾部。
void
add(int index,
E element)
将指定的元素插入此列表中的指定位置
boolean
addAll(
Collection<? extends
E> c)
boolean
addAll(int index,
Collection<? extends
E> c)
2.2删除功能
void
clear()
移除此列表中的所有元素。
Eremove
(int index)
移除此列表中指定位置上的元素。
boolean
remove(
Object o)
移除此列表中首次出现的指定元素(如果存在)。
2.3修改功能
Eset
(int index,
E element)
用指定的元素替代此列表中指定位置上的元素。
2.4获取功能
Eget
(int index)
返回此列表中指定位置上的元素。
int
indexOf(
Object o)
返回此列表中首次出现的指定元素的索引,或如果此列 表不包含元素,则返回 -1。
public int size()返回此列表中的元素数
2.5转换排序功能
Object[]
toArray()
按适当顺序(从第一个到最后一个元素)返回包含此列表中 所有元素的数组。
public <T> T[] toArray(T[] a)
按适当顺序(从第一个到最后一个元素)返回包含 此 列表中所有元素的数组,返回数组的运行时类型是指定数组的运行时类型。
2.6判断功能
public boolean isEmpty()如果此列表中没有元素,则返回 true
注意:ArrayList类没有重写Object类的equals()方法,使用时需要自己重写该方法。
3、案例1:ArrayList存储字符串并遍历
遍历方式:
Collection集合中的iterator()方法进行迭代器遍历
List集合中特有的listIterator()方法进行迭代器遍历
for循环(size()与 get(int index))
public class ArrayListDemo {
public static void main(String[] args) {
//1创建集合对象
ArrayListlist = new ArrayList();
//2添加字符串元素到集合
list.add("Hello");
list.add("Java");
list.add("hehe");
//3遍历
for (inti =0;i<list.size();i++) {
//获取到每一个元素,打印
System.out.println(list.get(i) +" " );
}
}
}
结果是:
Hello Java hehe
案例2:用ArrayList类中的方法去除集合中字符串的重复值(字符串的内容相同)。
public class ArrayListDemo {
public static void main(String[] args) {
//创建集合对象
ArrayListlist = new ArrayList();
//添加String对象到集合中
list.add("Java");
list.add("HTML");
list.add("CSS");
list.add("CSS");
list.add("CSS");
list.add("JavaScript");
System.out.println("原集合:"+list);
//a: 创建新的集合
ArrayListnewList =newArrayList();
//b: 遍历原有集合,得到每一个元素
for (inti=0;i<list.size();i++) {
//得到每一给元素
Object obj = list.get(i);
//c: 判断当前元素在新集合是否存在
if (newList.contains(obj)) {
//已经存在,不操作
} else {
//没有存在,存储进来
newList.add(obj);
}
}
System.out.println("新集合:"+newList);
}
}
结果是:
原集合:[Java, HTML, CSS, CSS, CSS,JavaScript]
新集合:[Java,HTML, CSS, JavaScript]
五、LinkedList类
1、描述:LinkedList类底层是双向链表,链表中的每个节点都包含了对前一个和后一个
元素的引用。
2、特有方法:
publicvoid addFirst(Object e)将指定元素插入此列表的开头
publicvoid addLast(Object e)将指定元素添加到此列表的结尾。
publicObject getFirst()返回此列表的第一个元素
publicObject getLast()返回此列表的最后一个元素。
publicObject removeFirst()移除并返回此列表的第一个元素。
publicObject removeLast()移除并返回此列表的最后一个元素。
3、案例
public class LinkedListDemo {
public static void main(String[] args) {
//1创建集合对象
LinkedListlist =newLinkedList();
//2添加元素
list.add("JavaSE");
list.add("JavaWEB");
System.out.println("初始元素:"+list);
//在元素的起始位置添加元素
list.addFirst("JavaEE");
System.out.println("在头添加"+list);
//在元素的末尾添加元素
list.addLast("Android");
System.out.println("在尾添加"+list);
//获取第一个元素
System.out.println("获取第一个元素:"+list.getFirst());
//获取最后一个元素
System.out.println("获取最后一个元素:"+list.getLast());
//删除第一个元素
Object obj = list.removeFirst();
System.out.println("被删除的第一个元素是:"+obj);
System.out.println("删除后的集合是:"+list);
//删除最后一个元素
Object obj2 = list.removeLast();
System.out.println("被删除的最一个元素是:"+obj2);
System.out.println("删除后的集合是:"+list);
}
}
结果是:
初始元素:[JavaSE,JavaWEB]
在头添加[JavaEE,JavaSE, JavaWEB]
在尾添加[JavaEE,JavaSE, JavaWEB, Android]
获取第一个元素:JavaEE
获取最后一个元素:Android
被删除的第一个元素是:JavaEE
删除后的集合是:[JavaSE,JavaWEB, Android]
被删除的最一个元素是:Android
删除后的集合是:[JavaSE,JavaWEB]
六、Vector类
1、描述:向量Vector类可以实现自动增长的对象数组,类似动态数组的功能。
Vector类从JDK1.0开始,从JDK1.2 开始,此类改进为可以实现 List
接口, 可使用List
接口取代Vector类,注意Vector
是同步的。
2、特有方法
void addElement(E e
)添加元素到集合,相当于List接口中的add(E e
)方法
EelementAt(int index)返回集合中给定位置上的元素,相当于List接口中 的get(int index)方法
Enumeration elements()返回此向量的组件的枚举,相当于List接口中的 iterator()方法
Enumeration接口中的方法:
boolean hasMoreElements()测试此枚举是否包含更多的元素,相当于Iterator<E>接口中的hasNext()方法。
ObjectnextElement()如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素,相当于Iterator<E>接口中的next()方法
3、案例
public class VectorDemo {
public static void main(String[] args) {
//创建集合对象
Vector v = new Vector();
//添加元素到集合
v.addElement("hello");
v.addElement("world");
//遍历
//普通for循环方式,size()与 get()
for (inti = 0;i < v.size();i++) {
System.out.println(v.elementAt(i) +" ");
}
System.out.println();
//迭代器方式
Enumerationen = v.elements();
//判断是否有下一个元素
while (en.hasMoreElements()) {
//获取下一个元素
System.out.print(en.nextElement()+" ");
}
}
}
结果是:
hello world
hello world
七、List集合下 ArrayList、Vector、LinkedList三者的区别?
ArrayList:
底层:数组结构,增删慢,查询快,线程不同步,效率高,不安全。
Vector:
底层:数组结构,增删慢,查询快,线程同步,效率低,安全。
LinkedList:
底层:链表结构,增删快,查询慢,线程不同步,效率高,不安全。