黑马程序员 集合

本文深入解析Java集合框架,包括Collection、List、Set、Map等核心接口及其典型实现类的特点与应用场景,通过实例演示集合的基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

集合是一种容器,可以存储各类对象进去。所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。


这个集合的作用看上去很像数组,同样是容器,那为什么要定义出集合呢,它与数组的区别在哪里?它有什么特点?

区别:

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
特点:
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型。


这样,就知道了集合出现的原因,接下来需要理解集合的框架的构成和分类:


从上图可以看出Collection接口是最主要的集合,其子接口List (列表),Set (集) 都有许多子类。同时还衍生出了Iterator迭代器和Map集合。

List:可存放重复元素,元素存取是有序的。
Set:不可以存放重复元素,元素存取是无序的。


List接口下的3个主要实现接口子类:

Vector:线程安全,但速度慢,已被ArrayList替代。
ArrayList:线程不安全,查询速度快。
LinkedList:链表结构,增删速度快。
取出LIst集合中元素的方式:
1. get(int index):通过脚标获取元素。
2. iterator():通过迭代方法获取迭代器对象。


下面用一个除去ArrayList集合中重复的元素为例,来说明集合的功能:

import java.util.*;

/*
     目的:去除ArrayList集合中的重复元素。
*/

public class ArrayListTest 
{
	//打印方法简写
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}

	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();

		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java02");
		al.add("java01");

		sop(al);  //除去重复元素前
		
		al = singleElement(al);

		sop(al);  //除去重复元素后
		

	}

	public static ArrayList singleElement(ArrayList al)
	{
		//定义一个临时容器用了存储集合中的无重复元素
		ArrayList newAl = new ArrayList();

		Iterator it = al.iterator();  //迭代器

		while(it.hasNext())
		{
			Object obj = it.next();

			if(!newAl.contains(obj)) //当新集合中没有obj时,存储进来
				newAl.add(obj);

		}

		return newAl;
	}
}
这样就能除去集合中的重复元素了。对集合中元素的操作要比对数组中元素的操作更加方便,所以在Java中集合是最常用的方法。


Set接口下的2个主要实现接口子类:

HashSet:线程不安全,存取速度快。
TreeSet: 线程不安全,可以对Set集合中的元素进行排序。
Set集合能保证其中元素的唯一性,它是如何做到的呢:

1. 先用hashCode方法得到其元素的返回值,若与集合中的任一元素都不同,则储存进集合。

2. 若集合中有返回值相同的元素,则再用equals方法比较两个元素,返回值为true,则判定为同一元素,不储存进集合;返回值为false,则判定不为同一元素,储存进集合。

这样便保证了集合中元素的唯一性。


TreeSet的最大特点是其具有排序的功能,它的底层数据结构是二叉树,它有两种实现排序的方式:

1. 让元素自身具备比较性:

这需要元素实现comparable接口,并覆盖compareTo方法,这种方式称为元素的自然顺序。

2. 让集合具备比较性:

当元素本身不具备比较性的时候,后者具备的比较性不是我们所需要的时候,就需要自己定义一个类,实现Comparator接口,覆盖compare方法,在将这个比较器作为参数传递给TreeSet集合的构造函数。


下面是一个按人名长度比较的例子:

package test;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class Test7 {

	public static void main(String[] args) {
		//创建一个Person集合,并添加3个元素
		Set<Person> s = new TreeSet<Person>(new StrlenComparator());
		s.add(new Person("zhangsan"));
		s.add(new Person("lisi"));
		s.add(new Person("zhaoliu"));
		//打印排序后的结果
		for(Person p: s){
			System.out.println(p.getName());
		}
	}
}

//定义Person类,必须初始化名字
class Person{
	private String name;
	Person(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
}

//自己定义个比较器,按照名字长度来排序
class StrlenComparator implements Comparator<Person>{
	public int  compare(Person p1, Person p2){
		//长度短的放二叉树左边,长得放右边,一样长则比较两个名字是否相同,相同则判断为同一个元素
		int num = p1.getName().length() - p2.getName().length();
		if(num==0)
			return  p1.getName().compareTo(p2.getName());
		else
			return num;
	}
}
打印结果按照定义的名字长度排序:

lisi
zhaoliu
zhangsan
可见对集合的操作各式各样,当我们需要什么功能时,便选择对应的集合来存储我们的元素,并对其进行想要的操作。


Map集合:
1. Map与Collection在集合框架中属并列存在
2. Map存储的是键值对
3. Map存储元素使用put方法,Collection使用add方法
4. Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
5. Map集合中键要保证唯一性


Map集合的3个常用实现子类:

1. Hashtable:线程安全,速度慢,不允许存放null键,null值,已被HashMap替代
2. HashMap:线程不安全,速度快,允许存放null 键,null值
3. TreeMap:对键进行排序,排序原理与TreeSet 相同

特别需要注意的是:

Map中的元素取出方式只有2种:1. entrySet()  2. keySet()。

都是先转换成Set集合后再用Set集合的方式取出。

下面是一个用了这两种方式对Map集合操作的例子:

package test;

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

public class Test8 {

	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();

		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("01","zhangsan1");
		map.put("04","zhangsan4");

		//将Map集合中的映射关系取出。存入到Set集合中。
		Set<Map.Entry<String,String>> entrySet = map.entrySet();

		Iterator<Map.Entry<String,String>> it = entrySet.iterator();

		while(it.hasNext())
		{
			Map.Entry<String,String> me = it.next();
			String key = me.getKey();  //映射关系中获取key,value的方法
			String value = me.getValue();
			System.out.println(key+":"+value);
		}

		/*
		//先获取map集合的所有键的Set集合,keySet();
		Set<String> keySet = map.keySet();

		//有了Set集合。就可以获取其迭代器。
		Iterator<String> it = keySet.iterator();

		while(it.hasNext())
		{
			String key = it.next();
			//有了键可以通过map集合的get方法获取其对应的值。
			String value  = map.get(key);
			System.out.println("key:"+key+",value:"+value);
		}
		*/
	}
}


集合与数组的互相转换:

因为集合方便操作,所以当我们需要对数组进行操作时可以转换成集合的形势,这样更加方便。当我们不想要其他人对集合中的元素进行操作时,也可以将集合转换为数组,以保证其安全性。

通过Arrays中的方法进行操作:

数组-->集合:Arrays.asList(T... a)

集合-->数组:

1. toArray(); 返回一个Object数组

2. toArray(T[] a); 返回指定的T数组









---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
### Java 高级集合进阶教程 #### Set 接口及其子类特性 Set接口是Java集合框架中的一个重要部分,它不允许存储重复元素。这使得`Set`非常适合用于去除重复项以及表示数学上的集合理论概念。 - **HashSet**: 实现了`Set`接口,内部基于哈希表实现[^3]。其特点是查找速度非常快,因为它是无序的,并且允许null值的存在(仅限一个)。为了保证元素唯一性,在向`HashSet`中添加对象时会调用该对象的`hashCode()`和`equals()`方法来判断是否已经存在相同元素。 ```java import java.util.HashSet; public class Student { private String name; public Student(String name){ this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Student other = (Student) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } ``` - **LinkedHashSet**: 继承自`HashSet`,除了具备后者所有的性质外还保持了插入顺序不变。这意味着当你迭代这个set的时候,你会按照最初加入这些项目的次序得到它们。 - **TreeSet**: 提供了一种有序的方式去保存元素,底层采用红黑树结构实现了排序功能。可以通过自然排序(`Comparable`)或定制比较器(`Comparator`)两种方式定义元素之间的大小关系。 #### Collection 和 Map 的区别与联系 在Java中,`Collection`是一个顶层接口,代表一组单一类型的对象列表。而`Map`则用来映射键到值之间的一对一关联,即每一对键都对应着唯一的值[^4]。 对于想要深入了解高级集合特性的开发者来说: - `Collection`适用于处理单列数据; - `Map`更适合于管理具有键值对形式的数据。 了解两者间的差异有助于选择合适的数据容器以满足特定应用场景的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值