单列集合学习笔记

单列集合

​ Collection被称为是单列集合,是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素;JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set接口、List接口)实现。

Collection接口通用的方法:

boolean add(Object o)
向集合中添加一个元素

boolean addAll(Collection c)
将指定集合c中的所有元素添加到该集合中

void clear()
删除该集合中的所有元素

boolean remove(Object o)
删除该集合中指定的元素

boolean removeAll(Collection c)
删除该集合中包含指定集合c中的所有元素

boolean isEmpty()
判断该集合是否为空

boolen contains(Object o)
判断该集合中是否包含某个元素

boolen containsAll(Collection c)
判断该集合中是否包含指定集合c中的所有元素

int size()
获取该集合个数

代码演示:

public static void main(String[] args) {
		
		//ArrayList为Collection接口的子接口List的一个实现类,有继承关系,因此可以调用它的所有方法
		Collection a = new ArrayList();//创建一个集合
		System.out.println(a);//尚未添加任何元素的集合
						
		String str = "111";
		a.add(111);//向集合中添加int类型123
		a.add(str);//添加字符串123
		System.out.println("a集合内的元素:"+a);
		
		Collection b = new ArrayList();//创建一个新集合
		b.add("bbb");
		b.add("222");
		
		a.addAll(b);//将指定集合coll2中的所有元素添加到b集合中
		System.out.println("把b集合添加到a中后:"+a);
		
		System.out.println( a.size() );//获取该集合个数
		
		System.out.println( a.contains("111") );//判断该集合中是否包含字符串"111"这个元素
		
		System.out.println( a.containsAll(b) );//判断该集合中是否包含指定集合b中的所有元素
				
		a.remove(111);//从集合中移除指定的int类型的111元素
		System.out.println("移除了int类型111后的a集合:"+a);
				
		a.removeAll(b);//移除a集合中包含有b集合的所有元素
		System.out.println("移除a集合中包含有b集合的所有元素"+a);
		
		a.clear();//删除该集合中的所有元素
		System.out.println(a);
		
		System.out.println(a.isEmpty());//判断该集合是否为空		
}

运行结果:

[]
a集合内的元素:[111, 111]
把b集合添加到a中后:[111, 111, bbb, 222]
4
true
true
移除了int类型111后的a集合:[111, bbb, 222]
移除a集合中包含有b集合的所有元素[111]
[]
true
List集合

​ List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合。

List集合特点:

​ 在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。

​ 另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。

List集合的两个常用实现类:

​ ArrayList集合:

​ 底层是数组,查询快,增删慢,线程不同步,效率高。

​ LinkedList集合:

​ 底层是链表,增删快,查询慢,线程不同步,效率高。LinkedList内部含有两个Node类型的First和last属性的双向循环链表结。

List集合常用的方法(只有在List接口的实现类才可用):

void add(int index,Object element)
将元素element插入在List集合的指定索引位置

bollean addAll(int index,Collection c)
将集合c包含的所有元素插入到List集合的指定索引位置

Object get(int index)
返回集合索引index处的集合

Object remove(int index)
删除index索引处的元素

Object set(int index,Object element)
将索引index处元素替换成element元素 并将替换后的元素返回

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

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

Object[] toArray()
将集合元素转换为数组

部分方法代码演示:

	/**
	 * 通过下标进行元素添加
	 */
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		list.add("西湖");
		list.add(1, "龙子湖");
		System.out.println("list:"+list);
		
		List list2 = new ArrayList();
		list2.add("鸡公山");
		list2.add("灵山");
		list2.add("老君山");
		System.out.println("list2:"+list2);
		
		list.addAll(1, list2);
		System.out.println("添加后的集合:"+list);
	}
/*程序运行结果:
list:[洞庭湖, 龙子湖, 鄱阳湖, 西湖]
list2:[鸡公山, 灵山, 老君山]
添加后的集合:[洞庭湖, 鸡公山, 灵山, 老君山, 龙子湖, 鄱阳湖, 西湖]
*/
	/**
	 * 通过下标移除元素
	 */
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		list.add("西湖");
		list.add(1, "龙子湖");
		System.out.println("list:"+list);
		
		//移除指定下标对应的元素
		list.remove(1);
		System.out.println("移除后的list:"+list);
		
		List list2 = new ArrayList();
		list2.add("灵山");
		list2.add("老君山");
		list2.add("西湖");
		//移除指定集合中有的元素
		list.removeAll(list2);
		System.out.println("移除后的list:"+list);
	}
/*程序运行结果
list:[洞庭湖, 龙子湖, 鄱阳湖, 西湖]
移除后的list:[洞庭湖, 鄱阳湖, 西湖]
移除后的list:[洞庭湖, 鄱阳湖]
*/
/**
 * 获取指定下标对应的元素
 */	
public static void main(String[] args) {
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		list.add("西湖");
		
		System.out.println("下标为1的元素:"+list.get(1));
}
/*程序运行结果:
下标为1的元素:鄱阳湖
*/

迭代器(Iterator)

​ 为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素,例如删除和获取集合中的元素,该对象就叫做迭代器(Iterator)。

​ 对 Collection 进行迭代的类,称其为迭代器。迭代器就是专门取出集合元素的对象。但是该对象比较特殊,不能直接创建对象(通过new),该对象是以内部类的形式存在于每个集合类的内部。

​ 如何获取迭代器?Collection接口中定义了获取集合类迭代器的方法(iterator()),所以所有的Collection体系集合都可以获取自身的迭代器。

Iterator迭代器的使用:

(1) 集合使用方法iterator()要求容器返回一个Iterator对象。注意:iterator()方法是Iterable接口中被Collection继承的方法。

(2) 使用next()获得序列中的下一个元素。第一次调用Iterator的next()方法时,它返回序列集合的第一个元素。

(3) 使用hasNext()检查序列中是否还有元素。

(4) 使用remove()将迭代器新返回的元素删除。

代码演示:

	/**
	 * 迭代器
	 */
	public static void main(String[] args) {
		List coll = new ArrayList();//创建一个列表集合
		coll.add("aaaa");
		coll.add(123);
		coll.add("bbbb");
        
		//调用集合中的iterator()方法获取一个迭代器,用于遍历coll集合
		Iterator it = coll.iterator();
        
        //初始指针在第一个元素位置之前,每次运行next(),迭代器的指针就往后移动一位,并返回该值
		System.out.println(it.next());
		System.out.println(it.next());
		System.out.println(it.next());
        
        //此时指针位置上已经没有元素,运行程序会出NoSuchElementException
		System.out.println(it.next());
	}
/*程序运行结果
aaaa
123
bbbb
Exception in thread "main" java.util.NoSuchElementException
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:970)
	at cn.study.test.Test.main(Test.java:31)
*/

	/**
	 * 迭代器(遍历移除操作)
	 */	

public static void main(String[] args) {
		List coll = new ArrayList();//创建一个列表集合
		coll.add("aaaa");
		coll.add(123);
		coll.add("bbbb");
		System.out.println(coll);
		
		Iterator it = coll.iterator();//获取一个迭代器,用于遍历coll集合
		//先通过指针去判断是否有下一个元素
		while(it.hasNext()) {
			//需求:当数据类型为Integer时,就删除该元素
			if(it.next() instanceof Integer) {
				it.remove();
			}
		}
		System.out.println("移除后的集合元素:"+coll);
}
/*运行结果
[aaaa, 123, bbbb]
移除后的集合元素:[aaaa, bbbb]
*/

​ 但是Iterator迭代器并不适合修改集合中的元素:

public static void main(String[] args) {
		List coll = new ArrayList();//创建一个集合
		coll.add("aaaa");
		coll.add(123);
		coll.add("bbbb");

		Iterator it = coll.iterator();//获取一个迭代器
		//先通过指针去判断是否有下一个元素
		while(it.hasNext()) {
            //如果遇见整型元素就在集合内添加新的元素
			if(it.next() instanceof Integer) {
				coll.add("ccc");//会出现并发修改异常(ConcurrentModificationException)
				//it.add("ccc");也不能这样
			}
		}
		System.out.println("移除后的集合元素:"+coll);
}

这时候就需要用到ListIterator迭代器:

​ Iterator迭代器是Java迭代器最简单的实现,为List设计的ListIterator迭代器具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

添加元素:

/**
 *用ListIterator迭代器向集合中添加元素
 */
public static void main(String[] args) {
		List coll = new ArrayList();//创建一个List集合
		coll.add("aaaa");
		coll.add(123);
		coll.add("bbbb");
		System.out.println(coll);
		
		ListIterator it = coll.listIterator();//获取一个列表迭代器
		
		//先通过指针去判断是否有下一个元素
		while(it.hasNext()) {
			
            //如果遇见整型元素就在集合内添加新的元素
			if( it.next() instanceof Integer) {
				//coll.add("ccc");不能这样写,在迭代中必须用列表迭代器的方法,如下
				it.add("ccc");//用列表迭代器中的方法在迭代时添加元素
			}
		}
		System.out.println(coll);
	}
/*运行结果
[aaaa, 123, bbbb]
[aaaa, 123, ccc, bbbb]
*/

查找元素:

	/**
	 * 用ListIterator迭代器在list集合中的指针查找
	 */
public static void main(String[] args) {
	
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		list.add("西湖");
			
		//获取ListIterator迭代器
		ListIterator listIt = list.listIterator();
			
		//ListIterator迭代器里的next()方法与Iterator迭代器里的next()方法功能相同
		//迭代器的初始指针在首元素之前,每调用一次next(),指针就会往后移动一位,然后返回该元素的值
		System.out.println(listIt.next());
		System.out.println(listIt.next());			
			
		//previous()方法的作用是返回当前值,然后指针往前移动
		System.out.println(listIt.previous());
		System.out.println(listIt.previous());
}
/*运行结果
洞庭湖
鄱阳湖
鄱阳湖
洞庭湖
*/

修改元素:

	/**
	 * 使用ListIterator迭代器中的set()方法在迭代的过程中修改集合中的元素
	 */	
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		list.add("西湖");
		System.out.println(list);
		
		//获取迭代器
		ListIterator listIt = list.listIterator();
		
		int i = 0;//手动创建一个集合下标
		while(listIt.hasNext()) {
			listIt.next();//每次循环都将指针往后移一位
			if(i%2 == 0) { //当下标为偶数,也就是,个数为奇数的元素将被修改
				
				//ListIterator中的set()方法修改当前指针的元素
				listIt.set("第"+(i+1)+"个湖");
			}
			i++;
		}
		System.out.println("修改后的集合:"+list);
	}
	

ListIterator迭代器中指针的问题:

	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("洞庭湖");
		list.add("鄱阳湖");
		System.out.println(list);
		
		//获取迭代器
		ListIterator listIt = list.listIterator();
		
		//初始指针在列表第一个元素前,调用next使指针向后移动到第一个元素的位置	
		listIt.next();
			
		//在目前指针的位置(第一个元素)后添加一个新元素,然后指针移动到新元素位置上
		listIt.add("西湖");
		
		//previous()返回当前位置的元素(然后使指针往前移动),当前位置的元素即新元素
		System.out.println(listIt.previous());

		System.out.println("添加元素后的集合:"+list);
	}
/*输出结果
[洞庭湖, 鄱阳湖]
西湖
添加元素后的集合:[洞庭湖, 西湖, 鄱阳湖]
*/
Set集合

​ Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

Set集合的特点:

  • 存储顺序和取出顺序不一定一致

  • 唯一(集合中元素不可重复,通过hashCode()和equals()方法比较是否唯一)

Set集合中常用的两个子类:HashSet和TreeSet

1.HashSet集合

​ HashSet集合底层数据结构是哈希表(是一个元素为链表的数组) ,哈希表底层依赖两个方法:hashCode()和equals()。由hashCode()和equals()保证元素唯一性。

代码演示:

	public static void main(String[] args) {
		Set set = new HashSet();//创建一个HashSet集合
		set.add("太平洋");
		set.add("北冰洋");
		set.add("大西洋");
		set.add("印度洋");
		set.add("北冰洋");//添入一个重复的值
		System.out.println(set);
	}
	

运行结果:

[北冰洋, 印度洋, 太平洋, 大西洋]//元素唯一,输出结果无序

**注意:**Set集合使用的是对象类中的hashCode()和equals()保证元素唯一性,如果没有重写对象类中的equals()方法,就默认使用继承自Object类的equals()方法,而Object类中的equals()方法默认比较的是地址值是否相同。因此地址值不同的对象添加进集合中时,不能保证集合中的对象属性值唯一。(编程软件可自动生成重写两个方法)

2.TreeSet集合

​ TreeSet集合是Set接口的实现,TreeSet 底层是TreeMap来实现的,TreeMap的底层是红黑树数据结构。

TreeSet集合的特点:

  • 将集合中的元素排序
  • 不能存储重复的元素

TreeSet集合的使用:

  • TreeSet():使用无参构造根据其元素的自然排序进行排序
  • TreeSet(new Comparator ):根据指定的比较器进行排序

​ TreeSet可以对集合中的元素进行排序,在添加元素的时候会自动去调用Comparable接口的compareTo方法。有些泛型类已经写好了排序规则,比如String 和 Integer 都已经实现了Comparable接口,也重写了compareTo方法。

常规排序:

存储Integer类型时代码演示:

//Integer类型会按照整数大小规则进行排序。代码中int类型数已经自动装箱成Integer类型
public static void main(String[] args) {
		Set set = new TreeSet();//创建一个TreeSet集合,然后添加整数
		set.add(13);
		set.add(11);
		set.add(12);
		System.out.println(set);
}
/*输出结果
[11, 12, 13]
*/

存储字符串类型时代码演示:

//String类是按照字典顺序的规则进行排序
public static void main(String[] args) {
		Set set = new TreeSet();//创建一个TreeSet集合,然后添加字符串
		set.add("bac");
		set.add("bca");
		set.add("acb");
		System.out.println(set);
}
/*输出结果
[acb, bac, bca]
*/

注意:TreeSet中存储的类型必须是一致的,不能一下存int,一下又存string,会出异常

自定义类型排序

​ TreeSet默认是自然排序,不能对自定义类型进行排序的,自定义的类存储的时候会出现异常(没有顺序)。

如果想要对自定义类型进行排序,有两种方案:

1、内部实现Comparable接口,重写compareTo方法

​ compareTo方法的返回值是用来判断集合中顺序的重要依据,用于确定自己的位置。

/**
 * 在类中实现Comparable接口,重写Comparable接口中的compareTo方法
 */
public class User implements Comparable{

	private int age;
	
	private String name;
	
	...
    
	@Override
	public String toString() {
		return   "年龄:"+ age +  " 名字:" + name ;
	}
	
	//重写comparaTo方法,先比较年龄,年龄相同就比较名字
	@Override
	public int compareTo(Object object) {
		User user = (User)object;//向下转型
		
		//创建一个变量,存放该对象的age变量和集合内对象的age变量的差值。
		int result = this.age - user.age;
		if(result == 0) {
			//如果年龄相同就用字符串中的compareTo()方法比较名字,并把比较值作为返回值
			return this.name.compareTo(user.name);
		}
		return result;//返回值用于TreeSet集合内部排序
	}
	
}
/**
 * 测试
 */
public static void main(String[] args) {
	   TreeSet ts = new TreeSet();//创建一个TreeSet集合
	   ts.add(new User(12,"abc"));//添加不同的对象
	   ts.add(new User(16,"aaa"));
	   ts.add(new User(14,"bbb"));
	   ts.add(new User(12,"bac"));
	   System.out.println(ts);//输出集合
}
/*输出结果
[年龄:12 名字:abc, 年龄:12 名字:bac, 年龄:14 名字:bbb, 年龄:16 名字:aaa]
*/

2、外部自定义一个比较器给集合,覆盖其本身的比较器

/**
 * 一个User类,有年龄和名字属性,重写了toString方法
 */
public class User {

	private int age;
	
	private String name;
	
	public User() {}

	public User(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	@Override
	public String toString() {
		return   "年龄:"+ age +  " 名字:" + name ;
	}	
}
/**
 * 自定义比较器
 */
public class CompareByInfo implements Comparator{

	@Override
	public int compare(Object object01, Object object02) {
		//向下转型成User类型
		User user01 = (User)object01;
		User user02 = (User)object02;
		int temp = user01.getAge() - user02.getAge();//比较年龄
		//年龄相同则比较名字
		if(temp == 0) {
			//getName方法获取名字字符串,用字符串类型中的compareTo方法比较两个对象的name变量值
			return user01.getName().compareTo(user02.getName());
		}
		return temp;//年龄不同时的返回值
	}
}
/*测试自定义比较器*/
public static void main(String[] args) {
       //创建一个TreeSet集合,把自定义的比较器给TreeSet集合
	   TreeSet ts = new TreeSet(new CompareByInfo());
	   ts.add(new User(12,"abc"));//添加不同的对象
	   ts.add(new User(16,"aaa"));
	   ts.add(new User(14,"bbb"));
	   ts.add(new User(12,"bac"));
	   System.out.println(ts);//输出集合
}
/*输出结果
[年龄:12 名字:abc, 年龄:12 名字:bac, 年龄:14 名字:bbb, 年龄:16 名字:aaa]
*/

02 = (User)object02;
int temp = user01.getAge() - user02.getAge();//比较年龄
//年龄相同则比较名字
if(temp == 0) {
//getName方法获取名字字符串,用字符串类型中的compareTo方法比较两个对象的name变量值
return user01.getName().compareTo(user02.getName());
}
return temp;//年龄不同时的返回值
}
}




```java
/*测试自定义比较器*/
public static void main(String[] args) {
       //创建一个TreeSet集合,把自定义的比较器给TreeSet集合
	   TreeSet ts = new TreeSet(new CompareByInfo());
	   ts.add(new User(12,"abc"));//添加不同的对象
	   ts.add(new User(16,"aaa"));
	   ts.add(new User(14,"bbb"));
	   ts.add(new User(12,"bac"));
	   System.out.println(ts);//输出集合
}
/*输出结果
[年龄:12 名字:abc, 年龄:12 名字:bac, 年龄:14 名字:bbb, 年龄:16 名字:aaa]
*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值