JAVA核心:集合类

1. 集合类概述

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

2. Collection 接口

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

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

public class Demo {
	public static void main(String[] args) {
		Collection c = new ArrayList();
		System.out.println("集合是否为空:" + c.isEmpty() + ",集合长度:" + c.size());

		c.add("你好");
		c.add(3.14);
		c.add(new Object());
		System.out.println("集合是否为空:" + c.isEmpty() + ",集合长度:" + c.size());

		c.remove(3.14);
		System.out.println("集合是否为空:" + c.isEmpty() + ",集合长度:" + c.size());

		Iterator it = c.iterator();
		while (it.hasNext()) {
			Object o = it.next();
			System.out.println(o);
		}
	}
}

运行结果:

集合是否为空:true,集合长度:0
集合是否为空:false,集合长度:3
集合是否为空:false,集合长度:2
你好
java.lang.Object@4361bd48

3. List集合

List集合包括List接口及List接口的所有实现类。List集合中的元素允许重复,各元素的顺序就是对象插入的顺序。用户可以通过使用索引来访问集合中的元素。

3.1 List接口

List接口继承了Collection接口,因此包含Collection中的所有方法,此外,List接口还定义了以下两个非常重要的方法。

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

3.2 List接口的实现类

List接口的常用实现类有ArrayListLinkedList

ArrayList类实现了可变的数组,允许所有元素,包括null,并可以根据索引位置对集合进行快速的随机访问。缺点是向指定的索引位置插入对象或删除对象的速度较慢。

LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入和删除对象,需要向集合中插入、删除对象时,使用LinkedList类实现的List集合的效率较好;但对于随机访问集合中的对象,使用LinkedList类实现List集合的效率较慢。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用List集合时通常声明为List类型,可通过不同的实现类来实例化集合。
在这里插入图片描述

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

public class Demo {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("清明时节雨纷纷");
		list.add("孤家寡人欲断魂");
		list.add("借问美女何处有");
		list.add("牧童遥指三里屯");

		list.remove(1);
		list.add(1, "我插一句……");
		list.set(1, "这句话我改了");
		list.add("牧童遥指三里屯");
		list.add("牧童遥指三里屯");
		list.add("牧童遥指三里屯");

		list.add(null);

		for (int i = 0; i < list.size(); i++) {
			System.out.println("list索引为" + i + "的元素:" + list.get(i));
		}

		System.out.println(list.size());

	}
}

运行结果:

list索引为0的元素:清明时节雨纷纷
list索引为1的元素:这句话我改了
list索引为2的元素:借问美女何处有
list索引为3的元素:牧童遥指三里屯
list索引为4的元素:牧童遥指三里屯
list索引为5的元素:牧童遥指三里屯
list索引为6的元素:牧童遥指三里屯
list索引为7的元素:null
8

4. set 集合

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

4.1 TreeSet

在这里插入图片描述
首先创建一个Person类:

public class Person implements Comparable {

	int id;
	int age;
	String name;

	public Person(int id, int age, String name) {// 点击Source->Generate Constructor using Fields
		super();
		this.id = id;
		this.age = age;
		this.name = name;
	}

	@Override
	public String toString() {// 点击Source->Generate toString()
		return "Person [id=" + id + ", age=" + age + ", name=" + name + "]";
	}

	@Override
	public int compareTo(Object o) {
		Person p;
		if (o instanceof Person) {
			p = (Person) o;
		} else {
			return -1;// 代表传入的参数比我本身小
		}
		int diff = this.id - p.id;
		if (diff != 0) {
			diff = diff / Math.abs(diff);// 差值除以本身绝对值,可以得到+1或-1
		}
		return diff;
	}

}

然后创建一个Demo类:

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class Demo {
	public static void main(String[] args) {
		Set set = new TreeSet();
		Person p1 = new Person(1, 18, "小明");
		Person p2 = new Person(2, 5, "大壮");
		Person p3 = new Person(3, 20, "阿强");

		set.add(p1);
		set.add(p2);
		set.add(p3);
		set.add(p1);// 重复的元素不会被添加到集合中
//		set.add(null);// TreeSet不能添加null值
		System.out.println(set.size());

		Iterator it = set.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}

	}
}

得到结果:

3
Person [id=1, age=18, name=小明]
Person [id=2, age=5, name=大壮]
Person [id=3, age=20, name=阿强]

可以看到,这里是根据id进行排序的。如果需要按照年龄排序,可以如下操作:

@Override
	public int compareTo(Object o) {
		Person p;
		if (o instanceof Person) {
			p = (Person) o;
		} else {
			return -1;// 代表传入的参数比我本身小
		}
		int diff = this.age - p.age;
		if (diff != 0) {
			diff = diff / Math.abs(diff);// 差值除以本身绝对值,可以得到+1或-1
		}
		return diff;
	}

将其中的id改为age即可,得到结果:

3
Person [id=2, age=5, name=大壮]
Person [id=1, age=18, name=小明]
Person [id=3, age=20, name=阿强]

4.2 HashSet

在这里插入图片描述
创建Person类:

public class Person {
	int id;
	String name;

	public Person(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + "]";
	}

	@Override
	public int hashCode() {// Source->Generate hashCode() and equals() 注意只勾选id
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (id != other.id)
			return false;
		return true;
	}

}

创建Demo类:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo {
	public static void main(String[] args) {
		Set set = new HashSet();
		Person p1 = new Person(1, "小明");
		Person p2 = new Person(2, "大壮");
		Person p3 = new Person(3, "阿强");
		Person p4 = new Person(2, "大壮");

		set.add(p1);
		set.add(p2);
		set.add(p3);
//		set.add(null);// 与TreeSet不同,HashSet可以添加null

//		p2.id = 5;
//		set.remove(p2);// id为5的hashCode,导致删除无效

		p2.name = "奥特曼";
		set.remove(p2);

		set.add(p4);

		System.out.println("集合的长度:" + set.size());

		Iterator it = set.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}

	}
}

运行结果:

集合的长度:3
Person [id=1, name=小明]
Person [id=2, name=大壮]
Person [id=3, name=阿强]

Hash算法比较复杂,建议回看原视频。

5. Map集合

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

5.1 Map接口

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

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

public class UpdateStu {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();// 创建Map实例
		map.put("01", "李同学");// 向集合中添加对象
		map.put("02", "魏同学");
		Set<String> set = map.keySet();// 构建Map集合中所有key对象的集合
		Iterator<String> it = set.iterator();
		System.out.println("key集合中的元素:");
		while (it.hasNext()) {// 遍历集合
			System.out.println(it.next());
		}
		Collection<String> coll = map.values();// 构建Map集合中所有value对象的集合
		it = coll.iterator();
		System.out.println("value集合中的元素:");
		while (it.hasNext()) {// 遍历集合
			System.out.println(it.next());
		}

	}

}

运行结果:

key集合中的元素:
01
02
value集合中的元素:
李同学
魏同学

5.2 Map接口的实现类

Map接口常用的实现类有HashMapTreeMap。建议使用HashMap类实现Map集合,因为由HashMap类实现的Map集合对于添加和删除映射关系效率更高。HashMap是基于哈希表的Map接口的实现,HashMap通过哈希码对其内部的映射关系进行快速查找;而TreeMap中的映射关系存在一定的顺序,如果希望Map集合中的对象也存在一定的顺序,应该使用TreeMap类实现Map集合。

在这里插入图片描述
在这里插入图片描述
首先创建Emp类:

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;
	}

}

在创建MapText类:

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

public class MapText {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();// 由HashMap实现的Map对象

		Emp emp = new Emp("351", "张雨绮");// 创建emp对象
		Emp emp2 = new Emp("512", "李健");
		Emp emp3 = new Emp("853", "王源");
		Emp emp4 = new Emp("125", "尼古拉斯赵四");
		Emp emp5 = new Emp("341", "黄贯中");

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

		Set<String> set = map.keySet();// 获取Map集合中的key对象集合
		Iterator<String> it = set.iterator();
		System.out.println("HashMap类实现的Map集合,无序:");
		while (it.hasNext()) {
			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("TreeMap类实现的Map集合,键对象升序:");
		while (iter.hasNext()) {
			String str = (String) iter.next();
			String name = (String) treemap.get(str);
			System.out.println(str + " " + name);
		}

	}

}

运行结果:

HashMap类实现的Map集合,无序:
341 黄贯中
125 尼古拉斯赵四
512 李健
853 王源
351 张雨绮
TreeMap类实现的Map集合,键对象升序:
125 尼古拉斯赵四
341 黄贯中
351 张雨绮
512 李健
853 王源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值