Java集合类

67 篇文章 16 订阅

Java中提供了不同的集合类,这些类具有不同的存储对象的方式,并提供了相应的方法以方便用户对集合进行遍历、添加、删除以及查找指定的对象。

1、集合类概述

Java语言的java.util包中提供了一些集合类,这些集合类又被称为容器。提到容器不难会想到数组,集合类与数组不同之处是,数组的长度是固定的,集合的长度是可变的;数组用来存放基本类型的数据,集合用来存放对象的引用。常用的集合有List集合、Set集合、Map集合,其中List与Set实现了Collection接口。各接口还提供了不同的实现类。上述集合类的继承关系如下图。

 

2、Collection接口

Collection接口是层次结构中的根接口。构成Collection的单位,被称之为元素。Collection接口通常不能直接使用,但该接口提供了添加元素、删除元素、管理数据的方法。由于List接口与Set接口都继承了Collection接口,因此这些方法对List集合与Set集合是通用的。

Collection接口的常用方法:

方法说明
boolean add(E e)将指定的对象添加到该集合中。
boolean remove(Object o)将指定的对象从该集合中移除。
boolean isEmpty()返回boolean值,用于判断当前集合是否为空。
Iterator<E> iterator()返回在此collection的元素上进行迭代的迭代器。用于遍历集合中的对象。
int size()返回int类型,获取该集合中元素的个数。
boolean contains(Object o)判断列表中是否存在指定元素。

通常遍历集合,都是通过迭代器(Iterator)来实现。Collection接口中的iterator()方法可返回在此Collection进行迭代的迭代器。

示例:实例化集合对象,并向集合中添加元素,最后将集合中的对象以String形式输出。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * 集合对象的使用示例
 * 
 * @author pan_junbiao
 *
 */
public class Muster
{
	public static void main(String[] args)
	{
		// 实例化集合类对象
		Collection<String> list = new ArrayList<String>();

		// 向集合添加数据
		list.add("pan_junbiao");
		list.add("KevinPan");
		list.add("pan_junbiao的博客");

		// 创建迭代器
		Iterator<String> it = list.iterator();

		// 判断是否有下一个元素
		while (it.hasNext())
		{
			// 获取集合中元素
			String str = (String) it.next();
			System.out.println(str);
		}

		// 判断列表中是否存在指定元素
		if (list.contains("pan_junbiao的博客"))
		{
			System.out.println("存在");
		} else
		{
			System.out.println("不存在");
		}
	}
}

注意:Iterator的next()方法返回的是Object类型。

执行结果:

 

3、List集合

List接口继承了Collection接口,因此包含Collection中的所有方法。List是有序集合,允许有相同的元素。此外,List接口还定义了以下两个非常重要的方法。

方法说明
get(int index)获得指定索引位置的元素。
set(int index , Object obj)将集合中指定索引位置的对象修改为指定的对象。

List接口的常用实现类有ArrayList、LinkedList和Vector。

3.1 ArrayList类

ArrayList是List接口的一个实现类,它实现了可变大小的数值,允许所有元素,包括null,并可以根据索引位置对集合进行快速的随机访问。

优点:在进行随机访问和遍历时,ArrayList提供更好的性能。

缺点:是向指定的索引位置插入对象或删除对象的速度较慢。

语法:

List<E> list = new ArrayList<>();

示例:实例化ArrayList集合对象,并对该集合进行元素的添加、删除、遍历的操作。

/**
 * ArrayList集合对象的使用示例
 * 
 * @author pan_junbiao
 *
 */
public class Gather
{
	public static void main(String[] args)
	{
		// 创建ArrayList集合对象
		List<String> list = new ArrayList<>();

		// 添加元素
		list.add("pan_junbiao");
		list.add("KevinPan");
		list.add("pan_junbiao的博客");

		// 删除元素
		list.remove(1);

		// 遍历集合(方式一)
		System.out.println("遍历集合(方式一):");
		for (int i = 0; i < list.size(); i++)
		{
			System.out.println(list.get(i));
		}

		// 遍历集合(方式二)
		System.out.println("\n遍历集合(方式二):");
		for (String s : list)
		{
			System.out.println(s);
		}
	}
}

执行结果:

3.2 LinkedList类

LinkedList是List接口的一个实现类,它提供了额外的addFirst()、addLast()、removeFirst()、removeLast()等方法,可以在LinkedList首部或者尾部进行插入或者删除操作。

优点:LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入和删除对象时,使用LinkedList类实现的List集合的效率较好。

缺点:对于随机访问集合中的对象,使用LinkedList类实现List集合的效率较慢。

语法:

List<E> list = new LinkedList<>(); 

LinkedList类的一些特殊方法:

方法说明
void addFirst(Object o)在列表的首部添加元素。
void addLast(Object o)在列表的尾部添加元素。
Object getFirst()返回列表中的第一个元素。
Object getLast()返回列表中的最后一个元素。
Object removeFirst()删除并返回列表中的第一个元素。
Object removeLast()删除并返回列表中的最后一个元素。

3.3 Vector类

Vector类具有一个与数组类似的数据结构,此结构是动态的,可以存储对象引用。一个Vector实例可以存储的元素为不同类的实例。其父类为AbstractList,它实现List接口。

Vector类提供4个构造方法:

构造方法说明
Vector()创建一个Vector对象。其初始容量为10,容量增量为0。
Vector(int initialCapacity)创建一个Vector对象,其初始容量有 initialCapacity 指定,其容量增量为0。
Vector(int initialCapacity, int capacityIncrement)创建一个Vector对象,其初始容量有 initialCapacity 指定,其容量增量由 capacityIncrement指定。
Vector(Collection<? extends E> c)创建一个包含给定集合元素的Vector对象。

Vector类的常用方法:

方法说明
void addElement(E obj)将指定的元素插入 Vector 对象的末尾处。
int capacity()返回 Vector 对象的元素数或容量。
boolean contains(Object o)如果 Vector 对象包含指定对象,返回 true。
void copyInto(Object[] anArray)将 Vector 的元素复制到指定的数组中。
E elementAt(int index)检索位于指定索引处的元素。
E firstElement()返回 Vector 中的第一个元素。
int indexOf(Object o)搜索 Vector 对象并返回第一个匹配对象的索引。
E lastElement()返回 Vector 对象中的最后一个元素。
void removeAllElements()从 Vector 对象中删除所有元素。
void setElementAt(E obj, int index)使用指定对象替换位于指定索引处的对象。
void insertElementAt(E obj, int index)将元素添加到 Vector 对象中 index 指定的位置。
String toString()返回表示 Vector 内容的格式化字符串。
int size()返回int类型,获取该集合中元素的个数。
void setSize(int newSize)根据 size 的值设置 Vector 对象的大小。

示例:Vector类的使用。

import java.util.Vector;

/**
 * Vector类的使用示例
 * 
 * @author pan_junbiao
 *
 */
public class vectorTest
{
	public static void main(String[] args)
	{
		// 创建一个Vector对象
		Vector<String> userVector = new Vector<String>();

		// 添加值
		userVector.add("Kevin");
		userVector.add("William");
		userVector.add("Andrew");

		// 插入值
		userVector.insertElementAt("pan_junbiao", 0);
		userVector.insertElementAt("pan_junbiao的博客", 4);

		// 显示值
		System.out.println("*****************************");
		System.out.println("显示内容:");
		for (String item : userVector)
		{
			System.out.print(item + "; ");
		}
		System.out.println("\n大小:" + userVector.size());

		// 搜索值
		System.out.println("*****************************");
		System.out.println("搜索内容:");
		String serchUser = "pan_junbiao的博客";
		if (userVector.contains(serchUser))
		{
			System.out.println("在索引" + userVector.indexOf(serchUser) + " 中找到:" + serchUser);
		}

		// 删除值
		userVector.removeElement("William");
		System.out.println("*****************************");
		System.out.println("删除用户名为William后的内容:");
		for (String item : userVector)
		{
			System.out.print(item + "; ");
		}
		System.out.println("\n大小:" + userVector.size());

		// 使用Vector类的其他方法
		System.out.println("*****************************");
		System.out.println("第一个元素为:" + userVector.firstElement());
		System.out.println("最后一个元素为:" + userVector.lastElement());
		System.out.println("默认容量:" + userVector.capacity());
	}
}

执行结果:

 

4、Set集合

Set集合中的对象不按特定的方式排序,只是简单地把对象加入集合中,但Set集合中不能包含重复对象。Set集合由Set接口和Set接口的实现类组成。Set接口继承了Collection接口,因此包含Collection接口的所有方法。

Set接口常用的实现类有HashSet类与TreeSet类。

HashSet类实现Set接口,有哈希表(实际上是一个HashMap实例)支持。它不保证Set的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。

TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,因此,TreeSet类实现的Set集合在遍历集合时按照自然顺序递增排序,也可以按照指定比较强递增排序,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。

TreeSet类增加的方法:

方法说明
E first()返回此 Set 中当前第一个(最低)元素。
E last()返回此 Set 中当前最后一个(最高)元素。
Comparator<? super E> comparator()返回对此 Set 中的元素进行排序的比较器。如果此 Set 使用自然顺序,则返回null。
SortedSet<E> headSet(E toElement)返回一个新的 Set 集合,新集合是 toElement (不包含)之前的所有对象。
SortedSet<E> subSet(E fromElement, E toElement)返回一个新的 Set 集合,是 fromElement (包含)对象与 toElement (不包含)对象之间的所有对象。
SortedSet<E> tailSet(E fromElement)返回一个新的 Set 对象,新集合包含对象 fromElement(包含)之后的所有对象。

示例:Set集合的示例,创建StuInfo类,实现 Comparable 接口,重写该接口中的 compareTo()方法。

import java.util.HashSet;
import java.util.TreeSet;

/**
 * Set集合的示例
 * 
 * @author pan_junbiao
 *
 */
public class StuInfo implements Comparable<Object> // 创建类实现 Comparable 接口
{
	int id; // 编号
	String name; // 姓名

	// 构造方法
	public StuInfo(int id, String name)
	{
		this.id = id;
		this.name = name;
	}

	public int getId()
	{
		return id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	// 重写排序方式
	public int compareTo(Object o)
	{
		StuInfo stuInfo = (StuInfo) o;
		int result = id > stuInfo.id ? 1 : (id == stuInfo.id ? 0 : -1);
		return result;
	}

	public static void main(String[] args)
	{
		// 创建学生信息对象
		StuInfo stu1 = new StuInfo(1, "kevinPan");
		StuInfo stu2 = new StuInfo(2, "pan_junbiao");
		StuInfo stu3 = new StuInfo(3, "pan_junbiao的博客");

		// 创建HashSet集合对象,并添加集合元素
		HashSet<StuInfo> stuHashSet = new HashSet<>();
		stuHashSet.add(stu1);
		stuHashSet.add(stu2);
		stuHashSet.add(stu3);

		// 遍历HashSet集合
		System.out.println("HashSet集合中的所有元素(无序):");
		for (StuInfo stu : stuHashSet)
		{
			System.out.println("编号:" + stu.getId() + "  姓名:" + stu.getName());
		}

		// 创建TreeSet集合对象,并添加集合元素
		TreeSet<StuInfo> stuTreeSet = new TreeSet<StuInfo>();
		stuTreeSet.add(stu1);
		stuTreeSet.add(stu2);
		stuTreeSet.add(stu3);

		// 遍历TreeSet集合
		System.out.println("\nTreeSet集合中的所有元素(有序):");
		for (StuInfo stu : stuTreeSet)
		{
			System.out.println("编号:" + stu.getId() + "  姓名:" + stu.getName());
		}
	}
}

执行结果:

 

5、Map集合

Map集合没有继承Collection接口,其提供的是key到value的映射。Map中不能包含相同的key,每个key只能映射一个value。key还决定了存储对象在映射中的存储位置,但不是由key对象决定的,而是通过一种“散列技术”进行处理,产生一个散列码的整数值。散列码通常用作一个偏移量,该偏移量对应分配给映射的内存区域的起始位置,从而确定存储对象在映射中的存放位置。Map集合包括Map接口以及Map接口的所有实现类。

5.1 Map接口

Map接口提供了将key映射到值的对象。一个映射不能包含重复的key,每个key最多只能映射到一个值。Map接口中同样提供了集合的常用方法,除此之外还包括如下表所示的常用方法。

Map接口中的常用方法:

方法说明
put(Object key,Object value)向集合中添加指定的key与value的映射关系。
containsKey(Object key)如果此映射包含指定key的映射关系,则返回true。
containsValue(Object value)如果此映射将一个或多个key映射到指定值,则返回true。
get(Object key)如果存在指定的key对象,则返回该对象对应的值,否则返回null。
keySet()返回该集合中所有key对象形成的Set集合。
values()返回该集合中所有值对象形成的Collection集合。
remove(Object key)删除由指定的键映射的“键-值对”。

示例:在项目中创建UpdateStu,在主方法中创建Map集合,并获取Map集合中所有key对象的集合和所有values值的集合,最有遍历集合。

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Map集合的使用示例
 * 
 * @author pan_junbiao
 *
 */
public class UpdateStu
{
	public static void main(String[] args)
	{
		// 创建Map实例
		Map<String, String> map = new HashMap<>();

		// 向集合中添加对象
		map.put("001", "pan_junbiao");
		map.put("002", "pan_junbiao的博客");

		// 获取与遍历Map集合中所有key对象的集合
		Set<String> set = map.keySet();
		System.out.println("key集合中的元素:");
		for (String key : set)
		{
			System.out.println(key);
		}

		// 获取与遍历Map集合中所有values值的集合
		Collection<String> coll = map.values();
		System.out.println("values集合中的元素:");
		for (String value : coll)
		{
			System.out.println(value);
		}
	}
}

执行结果:

5.2 Map接口的实现类

Map接口常用的实现类有HashMap和TreeMap。建议使用HashMap类实现Map集合,因为由HashMap类实现的Map集合对于添加和删除映射关系效率更高。HashMap是基于哈希表的Map接口的实现,HashMap通过哈希码对其内部的映射关系进行快速查找;而TreeMap中的映射关系存在一定的顺序,如果希望Map集合中的对象也存在一定的顺序,应该使用TreeMap类实现Map集合。
HashMap类是基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null键,但必须保证键的唯一性。 HashMap通过哈希表对其内部的映射关系进行快速查找。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

TreeMap类不仅实现了Map接口,还实现了java.util.SortedMap接口,因此,集合中的映射关系具有一定的顺序。但在添加、删除和定位映射关系时,TreeMap类比HashMap类性能稍差。由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定顺序排列的,因此不允许键对象是null。

示例:通过HashMap类实例化Map集合,并遍历该Map集合,然后创建TreeMap实例实现将集合中的元素顺序输出。

(1)首先创建Emp类:

/**
 * 员工信息类
 * 
 * @author pan_junbiao
 *
 */
public class Emp
{
	private String e_id;
	private String e_name;

	public Emp(String e_id, String e_name)
	{
		this.e_id = e_id;
		this.e_name = e_name;
	}

	public String getE_id()
	{
		return e_id;
	}

	public void setE_id(String e_id)
	{
		this.e_id = e_id;
	}

	public String getE_name()
	{
		return e_name;
	}

	public void setE_name(String e_name)
	{
		this.e_name = e_name;
	}
}

(2)创建测试主类:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * Map集合的使用示例
 * 
 * @author pan_junbiao
 *
 */
public class MapText
{
	public static void main(String[] args)
	{
		// 由HashMap实现的Map对象
		Map<String, String> map = new HashMap<>();

		// 创建Emp对象
		Emp emp1 = new Emp("351", "张三");
		Emp emp2 = new Emp("512", "李四");
		Emp emp3 = new Emp("853", "王一");
		Emp emp4 = new Emp("125", "pan_junbiao");
		Emp emp5 = new Emp("341", "pan_junbiao的博客");

		// 将对象添加到集合中
		map.put(emp1.getE_id(), emp1.getE_name());
		map.put(emp2.getE_id(), emp2.getE_name());
		map.put(emp3.getE_id(), emp3.getE_name());
		map.put(emp4.getE_id(), emp4.getE_name());
		map.put(emp5.getE_id(), emp5.getE_name());

		Set<String> set = map.keySet(); // 获取Map集合中的key对象集合
		Iterator<String> it = set.iterator();
		System.out.println("HashMap类实现的Map集合,无序:");
		while (it.hasNext())
		{ // 遍历Map集合
			String str = (String) it.next();
			String name = (String) map.get(str);
			System.out.println(str + " " + name);
		}
		TreeMap<String, String> treemap = new TreeMap<>(); // 创建TreeMap集合对象
		treemap.putAll(map); // 向集合添加对象
		Iterator<String> iter = treemap.keySet().iterator();
		System.out.println("\nTreeMap类实现的Map集合,键对象升序:");
		while (iter.hasNext())
		{ // 遍历TreeMap集合对象
			String str = (String) iter.next(); // 获取集合中的所有key对象
			String name = (String) treemap.get(str); // 获取集合中的所有values值
			System.out.println(str + " " + name);
		}
	}
}

执行结果:

 

6、总结:

(1)Collection是最基本的集合接口。List接口继承自Collection接口,List是有序集合,允许有相同的元素。Map提供键到值的映射。

(2)ArrayList是List接口的一个实现类,它实现了可变大小的数值,在进行随机访问和遍历元素时,它提供更好的性能。

(3)LinkedList是List接口的一个实现类,它提供了额外的addFirst()、addLast()、removeFirst()、removeLast()等方法,可以在LinkedList首部或者尾部进行插入或者删除操作。而且,相较于ArrayList类,在插入或者删除元素时,LinkedList提供更好的性能。

(4)HashMap是Map接口的实现类,实现一个键到值元素的哈希表。

 

7、ArrayList、LinkedList和Vector的区别

以下内容转载至博客园:https://www.cnblogs.com/zhangzongle/p/5432212.html

首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、LinkedList和Vector。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。3个具体实现类的相关区别如下:

(1)ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。

(2)Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问Vector比访问ArrayList慢。

(3)LinkedList是用链表结构存储数据,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,它还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。

(4)Vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而ArrayList是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。

(5)如果集合中的元素的数目大于目前集合数组的长度时,Vector增长率为目前数组长度的100%,而ArrayList增长率为目前数组长度的50%.如果在集合中使用数据量比较大的数据,用Vector有一定的优势。

(6)如果查找一个指定位置的数据,Vector和ArrayList使用的时间是相同的,都是0(1),这个时候使用Vector和ArrayList都可以。而如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用LinkedList,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号检索元素,但是插入数据要涉及到数组元素移动等内存操作,所以检索数据快,插入数据慢,Vector由于使用了 synchronized 方式(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号检索数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快。

(7)笼统来说:ArrayList:查询快(有索引的存在);LinkedList:增删改快。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pan_junbiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值