Java基础复习—集合

文章目录

        • 集合框架概述
        • Collection集合
            • add方法
            • contains方法
            • size、clear和isEmpty方法
            • addAll 和 containsAll 方法
        • Iterator接口
            • Remove方法
            • 使用增强型for循环遍历集合元素
        • List集合
            • List接口
            • ArrayList类
            • LinkedList类
        • 泛型
            • 泛型概念的提出
            • 什么是泛型

集合框架概述

​ 集合有时又称为容器,简单的说,它是一个对象,能将具有相同性质的多个元素汇聚成一个整体。

​ 集合被用于存储、获取、操纵和传输聚合的数据。

​ 在实际开发中,需要将使用的对象存储于特定的数据结构的容器中。JDK 提供了这样的容器——集合(Collection)和Map

如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qdvsf4OY-1591371282209)(C:\typora(日志)\JAVA基础复习日志\images\集合框架图.jpg)]

Collection 是一个接口,定义了集合相关的操作方法,其有两个子接口分别是 List 和 Set。Map 接口中有两个实现类分别是 HashMap 和 Hashtable(????)

在集合框架类中有很多实现类,不用每个都掌握,只需要掌握常用的就行

Collection集合

​ 一个集合代表一组对象,这些对象作为集合的元素。

​ 在 Java 集合框架中定义的 Collection 接口,提供了集合接口的通用操作,通常用于传递集合对象。

Collection 接口是 Set 接口和List 接口的父接口,提供了大量的、通用的集合操纵方法

add方法

​ Collection 定义了一个 add 方法用于向集合中添加新元素: Boolean add(E e)

​ 该方法会将给定的元素添加进集合中,若添加成功则返回true,否则返回false

具体如下:

public class Collection {
	public static void main(String[] args) {
		ArrayList coll = new ArrayList();
		coll.add(1);
		coll.add(1);
		coll.add(1);
		System.out.println(coll);//[1,1,1]
	}
}
contains方法

Boolean contains(Object o)

该方法用于判断给定的元素是否包含在集合中,若包含则返回true,否则返回false。需要注意的是,集合在判断元素是否被包含在集合中,是根据每个元素的 equals() 方法进行比较后的结果,通常需要重写 equals() 方法,保证 contains 方法的合理结果

实际案例:略

size、clear和isEmpty方法

(1) int size():该方法用于返回当前集合中的元素总数

(2) void clear():该方法用于清除当前集合

(3) boolean isEmpty():该方法用于判断当前集合是否不包含任何元素(返回集合是否为空)

具体如下:

import java.util.ArrayList;
import java.util.List;

public class Collection {
	public static void main(String[] args) {
        //传入字符串型的元素
		List<String> list = new ArrayList<String>();
		System.out.println(list.isEmpty());//true
		list.add("java");
		list.add("c");
		list.add("#c");

		System.out.println("isEmpty:"+list.isEmpty()+"\nsize:"+list.size());
        //清除集合元素
		list.clear();
		System.out.println("isEmpty:"+list.isEmpty()+"\nsize:"+list.size());
	}
}
/*运算结果:
	true
isEmpty:false
size:3
	isEmpty:true
	size:0
*/

上述程序中 List 在定义时加了一个 < String> ,该语法是泛型,后续将介绍。作用是要求 list 集合中只能存储 Stirng 类型的元素,如果不加泛型,集合可以存放任意类型的元素

addAll 和 containsAll 方法

(1) Boolean addAll(Collection c):该方法需要传入一个集合,并将该集合中所有元素添加到当前集合中

(2) Boolean containsAll(Collection c):该方法用于判断当前集合是否包含给定集合中的所有元素,若包含则返回 true

具体如下:

import java.util.ArrayList;
import java.util.List;

public class CollectionDemo {
	public static void main(String[] args) {
		List<String>  c = new ArrayList<String>();
		c.add("Java");
		c.add("C");
		c.add("PHP");
		System.out.println(c);
		List<String>  c1 = new ArrayList<String>();
		//将集合C中的所有元素传入到集合C1中去
		c1.addAll(c);
		System.out.println(c1);
		
		List<String>  c2 = new ArrayList<String>();
		c2.add("java");
		c2.add("PHP");
		System.out.println(c2);
        //判断集合C是否包含集合C2中的所有元素
		System.out.println(c.containsAll(c2));
		
	}
}/*远算结果:[Java, C, PHP]
            [Java, C, PHP]
            [java, PHP]
            true
*/

Collection中除了上述例句的方法以外,还有其他很多方法,方法如下

(1) boolean add(object o):该方法用于向集合里添加一个元素

(2) boolean addAll(Collection c):该方法把集合c里的所有元素添加到指定集合里

(3) void clear():清楚集合里的所有元素,将集合长度变为0

(4) boolean contains(Object c):

(5) boolean containsAll(Object c):

(6) boolean isEmpty():返回集合是否为空。当集合长度为0时返回true,否则返回false

(7) Iterator iterator():返回一个Iterator对象,用于遍历集合里的元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOpDqDgO-1591371282211)(C:\typora(日志)\JAVA基础复习日志\images\Iterator.png)]

代码如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CollectionDemo {
	public static void main(String[] args) {
		List<String>  c = new ArrayList<String>();
		c.add("Java");
		c.add("C");
		c.add("PHP");
		System.out.println(c);
		
		//遍历集合里的元素
		Iterator<String> it = c.iterator();
		//hasNext
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}/*远算结果:[Java, C, PHP]
                Java
                C
                PHP
*/

(8) boolean remove(Object o):删除集合中的指定元素o,当集合包含了一个或多个元素o时,这些元素将被删除,该方法返回true

(9) boolean removeAll(Object c):从集合中删除集合c里包含的所有元素。。。。。。

(10) boolean retainAll(Collection c):从集合中删除集合c里不包含的元素

(11) int size():返回集合里元素的个数

(12) Object[] toArray():把集合转换成一个数组,所有集合元素变成对应的数组元素

通过上述代码以及运行程序后的结果,可以看出Collection的用法有添加、删除、返回元素个数以及清除元素等

Iterator接口

​ Iterator 接口也是Java集合框架中的成员,但它与 Collection 系列、Map系列的集合不一样。Collection 系列集合、Map系列集合主要用于盛装其他对象

迭代:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。重复执行一系列运算步骤,从前面的量依次求出后面的量的过程

而 Iterator 则主要用于遍历(即 迭代访问 )Collection 集合中的元素,Iterator 对象也被称为迭代器

​ Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的同一编程接口。

Iterator 接口定义了如下3个方法

(1) boolean hasNext():如果被迭代的集合元素还没有被遍历,则返回true

(2) Object next():返回集合里下一个元素

(3) void remove():删除集合里上一次next方法返回的元素

具体代码如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("JAVA");
		list.add("C");
		list.add("PHP");
		System.out.println(list);
		//获取list集合对应的迭代器
		Iterator itera = list.iterator();
		while(itera.hasNext()) {
			//itera.next() 方法返回的数据类型是Object类型,需要强制转换
			String str = (String) itera.next();
			System.out.println(str);
            
            /*对迭代变量str进行赋值,但再此输出时集合元素并没有发生改变。
           结论:当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给迭代变量,
            	而是把集合元素的值传给迭代变量,所以修改迭代变量的值对元素本身没有任何影响
            */
			str="测试字符串";
		}
        //测试输出行
		System.out.println(list);
	}
}
/*运算结果:
        [JAVA, C, PHP]
        JAVA
        C
        PHP
        [JAVA, C, PHP]
*/

从上面代码中可以看出,Iterator 仅用于遍历集合,本身并不提供盛装对象的能力。如果要创建Iterator对象,则必须有一个被迭代的集合。没有集合的Iterator就没有存在的价值

Remove方法

Iterator 必须依附于 Collection 对象,若有一个 Iterator 对象,则必然有一个与之关联的 Collection 对象

​ Iterator 提供了两个方法来迭代访问 Collection 集合里的元素,并可以通过 Remove() 方法来删除集合中上一个 next() 方法返回的集合元素

​ 在使用迭代器遍历集合时,不能通过集合的 remove() 方法删除集合元素,否则会抛出并发生异常。我们只能通过使用Iterator 迭代器自身的 remove() 方法来删除通过 next() 迭代出来的元素

使用方式

迭代器的删除方法是在原集合中删除元素,需要注意的是,在调用 remove() 方法前必须通过迭代器 next() 方法迭代过的元素。这样删除的才是这个元素,而且删除后的不能再次调用 remove( )方法,除非再次调用 next() 方法

当 Iterator 用作迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变,只能通过 Iterator的 remove() 方法删除上一次 next() 方法返回的集合元素才可以,否则会发生异常java. util. Concurrent Modification Exception

代码如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorRemove {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("JAVA");
		list.add("C");
		list.add("C#");
		list.add("PHP");
		Iterator iter = list.iterator();
		while(iter.hasNext()) {
			//强制转换
			String ite = (String) iter.next();
			if(ite.equals("JAVA")) {
				iter.remove();
			}else if(ite.equals("C")) {
				iter.remove();
			}
		}
       	//将元素 "Pytsom" 插入到 List 集合中的 1 处(相当于数组)
		list.add(1, "Pytsom");
		System.out.println(list);
        //集合转换数组
		Object[] arr = list.toArray();
		for(int i=0;i<arr.length;i++) {
			System.out.println(arr[i]+" ");
		}
	}
}
/*运算结果:
        [C#,Pytsom,PHP]
        C#
        Pytsom
        PHP 
*/
使用增强型for循环遍历集合元素

​ Java5.0之后推出一个新的特性,增强for循环,也成为新循环。该循环不同于传统的循环工作,其只用于遍历集合或者数组,语法如下:

for(元素类型 e:集合或数组){
    循环体;
}

​ 新循环并非新的语法,而是在编译过程中,编译器会将新循环转换为迭代器模式,所有循环本质上是迭代器

具体代码如下:

import java.util.ArrayList;
import java.util.List;

public class ForeachText {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("JAVA");
		list.add("C");
		list.add("C#");
		list.add("PHP");
		for(Object e:list) {
            //强制转换
			String book = (String) e;
			System.out.println(book);
			if(book.equals("JAVA")) {
                //使用Foreach循环时集合元素不可以发生改变,此处代码会发生异常
				list.remove(book);
			}
			System.out.println(list);
		}
	}
}

List集合

​ List是有序的 Collection ,使用此接口能够精确地控制每个元素插入的位置。用户能够使用索引(元素在List的位置,类似于数组下标)来访问List中的元素,这类似于数组,且List允许有相同的元素。

​ 除了从 Collection 继承过来的操作外,List接口还包括以下操作:

(1) 按位置访问:根据元素在序列中的位置索引访问元素

(2) 查找:在序列中查找指定的对象,并返回其位置索引

(3) 迭代:扩展了 Iterator 接口,以利用序列的顺序特征

(4) List子集合:在序列上执行任何范围的操作

List接口

​ List 作为 Collection 接口的子接口,当然可以使用 Collection 接口里的全部方法,而且由于 List 是有序集合,因此 List 集合里添加了一些根据索引来操作集合元素的方法。

(1) void add(int index,Object e):将元素 e 插入到 List 集合中的 index 处

(2) boolean addAll(int index,Collection e):将集合 c 所包含的所有元素插入到 List 集合的 index 处

(3) Object get(int index):返回集合 index 索引处的元素

(4) int indexOf(Object o):返回对象 o 在 List 集合中第一次出现的位置索引

(5) int lastIndexOf(Object o):返回对象 o 在 List 集合中最后一次出现的位置索引

(6) Object remove(int index):删除并返回 index 索引处的元素

​ **(7) ** Object set(int index,Object e):将 index 索引处的元素替换成 e 对象,返回新元素

(8) List subList(int a,int b):返回从索引 a (包含) 到索引 b (不包含)处所有集合组成的子集合

​ 所有的 List 实现类都可以调用这些方法来操作集合元素。与Set集合(不理解)相比,List 增加了根据索引来插入、替换和删除集合元素的方法

代码如下所示:

import java.util.ArrayList;
import java.util.List;

public class CollectionListDemo {
	public static void main(String[] args) {
		List books = new ArrayList();
		//向集合中添加三个元素
		books.add(new String("JAVA"));
		books.add(new String("PHP"));
		books.add(new String("C##"));
		System.out.println(books);	//[JAVA, PHP, C##]
		//插入元素
		books.add(1, new String("Web"));
		System.out.println(books);	//[JAVA, Web, PHP, C##]
		//for循环,get()方法输出集合元素
		for(int i=0;i<books.size();i++) {
			System.out.println(books.get(i));
		}
		
		//删除下标为2的元素
		books.remove(2);
		System.out.println(books);	//[JAVA, Web, C##]
		//获得索引位置
		System.out.println(books.indexOf(new String("JAVA")));	//0
		//替换元素
		books.set(0, new String("PHP"));
		System.out.println(books);	//[PHP, Web, C##]
		
		//截取子集合,相当于Strng类的subString方法。
		System.out.println(books.subList(1,3));	//[Web, C##]
	}
}

​ 上述代码中,List 集合可以根据位置索引来访问集合中元素的位置,因此 List 增加了一种新的遍历集合元素的方法:使用普通的for循环来遍历集合元素

ArrayList类

​ 实现List接口的常用类有:LinkedList、ArrayList和Vector、Stack

​ LinkedList的用法和ArrayList用法基本相同,但两者的性能不同。

ArrayList 集合在添加和删除时比 LinkedList 慢,ArrayList 集合在查询时比 LinkedList 集合要快

ArrayList 实现了可变大小的数组。它允许所有元素,包括 Null 。ArrayList 没有同步

下面为一个ArrayList的实例代码:

import java.util.ArrayList;

public class ArrayListDome {
	public static void main(String[] args) {
		ArrayList<SList> arr = new ArrayList<SList>() {
			{
				add(new SList("zhangsan",19));
				add(new SList("lisi",19));
			}
		};
		System.out.println("集合的长度为:"+arr.size());
		arr.remove(0);
		System.out.println(arr);
	}
}
class SList{
	String name;
	int age;
	public SList(String name,int age) {
		this.name=name;
		this.age=age;
	}

}
/*运算结果:
        集合的长度为:2
        [day01.SList@28a418fc]
*/
LinkedList类

​ LinkedList 类是 List 接口的实现类,这意味着它是一个 List 集合,可以利用索引来随机访问集合中的元素

​ 除此之外,LinkedList 还实现了 Deque 接口,因此它可以被当成双端队列来使用,自然也可以被当成“栈”来使用。

LinkedList集合的用法

import java.util.LinkedList;

public class LinkedListDome {
	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		//将字符串元素加入栈的顶部
		link.offer("JAVA");
		//将一个字符串元素加入栈的顶部
		link.push("PHP");
		//将字符串元素添加到队列的头部(相当于栈的顶部)
		link.offerFirst("C##");
		for(int i=0;i<link.size();i++) {
			System.out.println(link.get(i));
		}//C## PHP JAVA
        
		//访问但不删除栈顶的元素
		System.out.println(link.peekFirst());
		//访问但不删除队列的最后一个元素
		System.out.println(link.peekLast());
        
		//将栈顶的元素 弹出"栈"
		System.out.println(link.pop());//[PHP, JAVA]
		System.out.println(link);
        
		//访问并删除队列的最后一个元素
		System.out.println(link.pollLast());
		System.out.println(link);//[PHP]
	}
}

​ LinkedList 与 ArrayList 的实现机制完全不同,ArrayList 内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能

​ 而 LinkedList 内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能比较差,但在差入、删除元素时性能比较好

泛型

泛型概念的提出

首先,我们先看下列代码:

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
	public static void main(String[] args) {
		List links = new ArrayList();
		links.add("PHP");
		links.add("C##");
        
        //报错
		links.add(100);
		for(int i=0;i<links.size();i++) {
            //改为 Object 类型可以输出
			String Str = (String) links.get(i);
			System.out.println(Str);
		}
	}
}
/*运算结果:
        PHP
        C##
        报错:java.lang.ClassCastException
*/

​ 在上述的编码过程中,我们发现主要的两个问题:

(1) 当我们将一个对象放入集合中,集合不会记住此类型对象的类型,当再次从集合中取出对象时,该对象的编译类型变成了 Object 类型,但其运行时类型任然为其本身类型。

(2) 但取出集合元素时需要人为的强制类型转换到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常

那么有没有什么办法可以使集合能够记住集合内元素各类型,且能达到只要编译时不出问题,运行时就不会出现“java.lang.ClassCastException”异常呢?答案就是:使用泛型

什么是泛型

​ 泛型,即“参数化类型”。

​ 一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。

​ 那么,参数化类型怎么理解呢?顾名思义,就是将类型有原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后使用/调用时传入的具体类型(类型实参)。看着有些复杂,首先看下面的例子采用泛型的写法。

具体如下:

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
	public static void main(String[] args) {
		List links = new ArrayList();
		links.add("PHP");
		links.add("C##");
		links.add(100);
        //  泛型
		List<String> lists = new ArrayList<String>();
		lists.add("PHP");
		lists.add("C##");
		//lists.add(100);报错,只能传入字符串类型的
		for(int i=0;i<lists.size();i++) {
			//不需要强制转换,不报错
			String lis = lists.get(i);
			System.out.println(lis);
		}
	}
}

式(可以称之为类型形参),然后使用/调用时传入的具体类型(类型实参)。看着有些复杂,首先看下面的例子采用泛型的写法。

具体如下:

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
	public static void main(String[] args) {
		List links = new ArrayList();
		links.add("PHP");
		links.add("C##");
		links.add(100);
        //  泛型
		List<String> lists = new ArrayList<String>();
		lists.add("PHP");
		lists.add("C##");
		//lists.add(100);报错,只能传入字符串类型的
		for(int i=0;i<lists.size();i++) {
			//不需要强制转换,不报错
			String lis = lists.get(i);
			System.out.println(lis);
		}
	}
}

你可能感兴趣的:(java基础)