Java知识总结-集合二


说明:Set集合中TreeSet和HashSet集合的存储原理是重点。


一,集合体系中常见实现类。

List接口常见实现类:

List集合中元素是有序的(即元素存入和去除的顺序是一致的),集合中元素可以重复,该集合体系有索引。

List集合判断元素是否相同,依据元素的equals方法。

实现类一:

ArrayList:

底层的数据结构使用的是数组结构。特点:查询元素块,但是增删稍慢,线程不同步,集合长度可变(默认=初始长度为10)超过容量时集合以50%自动增长;

实现类二:

LinkedList:

底层的数据结构使用的是链表结构。特点:增删速度很快,查询稍慢;

实现类三:

Vector:

底层数据结构为数组结构。特点:线程同步,效率较低,被ArrayLIst替代;


Set接口常见实现类;

Set集合中元素是无序的,元素不能重复。

实现类一:

HashSet:

底层数据结构是哈希表。

HashSet集合实现元素唯一性的方式:当向集合中存入元素时,判断该元素hashcode()方法的值与集合中原有元素的hashcode()值进行比较,如果不同,则认为集合中没有该元素,并向集合中存入该元素。当该元素与集合中原有元素的hashcode()值有相同时,系统会继续调用该元素的equals()方法,如果结构仍为true()则认为集合中已经存在该元素,不再存入。如果equals()结果为false(),则认为是不同的元素,并向集合中添加该元素。

注意:元素进入HashSet集合(即元素地址的哈希值进入HashSet集合),集合根据元素的哈希值排列元素顺序,与元素进入集合的顺序不一定相同。

由于Object类中的equals()方法是根据对象地址来判断结果的,所以在存入集合的元素对象一般会复写 hashcode()方法和equals()方法。

HashSet集合总判断元素是否存在,以及删除等操作都依赖于元素的hashcode()方法和equals()方法。

实现类二;

TreeSet:

底层数据结构式二叉树。

TreeSet集合可以对集合中的元素排序,默认排序方式为自然排序。

TreeSet集合保证集合元素唯一性的依据:当元素的compareTo()方法结果为0时,认为两元素相同。

TreeSet集合排序有两种方式:

第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖接口的compareTo()方法,这种方式称为元素的自然顺序排序。

第二种方式:当元素本身不具备比较性,或者具备的比较性不是集合所需要的,在初始化集合时,会为集合定义比较器:先自定义一个比较器,将比较器对象做为参数传递黑TreeSet集合的构造函数。


二,HashSet集合示例

例1.当向HashSet集合中添加相同元素时,集合不会存入重复元素;

import java.util.*;
public class Test {
	public static void main(String[] args){
		//创建集合
		HashSet hs=new HashSet();
		//为集合添加元素
		hs.add("aaa");
		hs.add("bbb");
		hs.add("ccc");
		//当添加元素失败是,add()方法返回false.
		System.out.println(hs.add("aaa"));
		System.out.println(hs.add("bbb"));
		//打印集合
		System.out.println(hs);
		
	}
}

运行结果:

false
false
[aaa, ccc, bbb]

从运行结果可以看出,当为HashSet集合添加已有元素时,添加失败,此时系统自动调用了字符串的hashcode()方法来判断字符串是否相同。


例2:向HashSet集合中添加自定义Student类对象,当Student对象姓名和年龄都相同时默认为同一个对象。

import java.util.*;
public class Test {
	public static void main(String[] args){
		//创建集合
		HashSet hs=new HashSet();
		//为集合添加元素
		hs.add(new Student("aaa",11));
		hs.add(new Student("bbb",22));
		hs.add(new Student("ccc",33));
		hs.add(new Student("aaa",44));
		hs.add(new Student("ddd",33));
		hs.add(new Student("aaa",11));//姓名和年龄与已有元素都相同
		//打印集合
		System.out.println(hs);
		
	}
}
class Student{
	private String name;
	private int age;
	Student(String name,int age){
		this.name=name;
		this.age=age;
	}
	//复写hashcode()方法
	public int hashcode(){
		return this.name.hashCode()+this.age*31;
	}
	//复写equals()方法
	public boolean equals(Object obj){
		if(!(obj instanceof Student))
			return false;
		Student stu=(Student)obj;
		//当两对象姓名年龄都相同时返回true
		return this.name.equals(stu.name)&&this.age==stu.age;
	} 
	//复写toString()方法
	public String toString(){
		return this.name+"--"+this.age;
	}
}

运行结果:

[aaa--44, ccc--33, aaa--11, aaa--11, bbb--22, ddd--33]

通过结果可以看到,只有姓名和年龄都相同时,才被认为是同一元素,


三,TreeSet集合示例

例1:在TreeSet集合中添加字符串,看集合是否为字符串自动排序

import java.util.*;
public class Test {
	public static void main(String[] args){
		//创建集合
		TreeSet ts=new TreeSet();
		//为集合添加元素
		ts.add("xx");
		ts.add("aa");
		ts.add("yy");
		ts.add("kk");
		ts.add("cc");
		ts.add("bb");
		//打印集合
		System.out.println(ts);
	}
}

运行结果:

[aa, bb, cc, kk, xx, yy]

从结果可以看出,集合为元素进行了自然排序。


例2:向集合中添加自定义 Student类对象,并按照对象的年龄属性排序,当年龄相同时,按姓名的自然顺序排序。

import java.util.*;
public class Test {
	public static void main(String[] args){
		//创建集合
		TreeSet ts=new TreeSet();
		//为集合添加元素
		ts.add(new Student("aaa",66));
		ts.add(new Student("xxx",22));
		ts.add(new Student("kkk",55));
		ts.add(new Student("ddd",44));
		ts.add(new Student("ddd",33));
		ts.add(new Student("aaa",11));//
		//打印集合
		System.out.println(ts);
	}
}
class Student implements Comparable{ //实现Comparable接口
	private String name;
	private int age;
	Student(String name,int age){
		this.name=name;
		this.age=age;
	}
	//复写hashcode()方法
	public int hashcode(){
		return this.name.hashCode()+this.age*31;
	}
	//复写equals()方法
	public boolean equals(Object obj){
		if(!(obj instanceof Student))
			return false;
		Student stu=(Student)obj;
		//当两对象姓名年龄都相同时返回true
		return this.name.equals(stu.name)&&this.age==stu.age;
	} 
	//复写compareTo()方法
	public int compareTo(Object obj){
		if(!(obj instanceof Student))
			throw new RuntimeException("不是Student对象");
		Student stu=(Student)obj;
		int num=this.age-stu.age;
		if(num==0)
			return this.name.compareTo(stu.name);
		return num;
	}
	//复写toString()方法
	public String toString(){
		return this.name+"-"+this.age;
	}
}

运行结果:

[aaa-11, xxx-22, ddd-33, ddd-44, kkk-55, aaa-66]

通过结果可以看到,集合实现了我们自定义的排序方式,将元素按照年龄大小进行排序。


例3:向集合中添加自定义 Student类对象,且不按照Student类自定义的比较方式排序,而是通过传递比较器的方式按照姓名进行排序。当姓名相同时按照年龄的自然顺序排序。

import java.util.*;
public class Test {
	public static void main(String[] args){
		//创建集合,并传递自定义的比较器
		TreeSet ts=new TreeSet(new MyCom());
		//为集合添加元素
		ts.add(new Student("aaa",66));
		ts.add(new Student("xxx",22));
		ts.add(new Student("kkk",55));
		ts.add(new Student("ddd",44));
		ts.add(new Student("ddd",33));
		ts.add(new Student("aaa",11));//
		//打印集合
		System.out.println(ts);
	}
}
//自定义一个按照学生姓名排序的比较器
class MyCom implements Comparator<Student>{
	public int compare(Student s1,Student s2){
		int num=s1.getName().compareTo(s2.getName());
		if(num==0)
			return s1.getAge()-s2.getAge();
		return num;
	}
}
//自定义类并实现Comparable接口,使该类对象具备比较性
class Student implements Comparable{
	private String name;
	private int age;
	Student(String name,int age){
		this.name=name;
		this.age=age;
	}
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
	//复写hashcode()方法
	public int hashcode(){
		return this.name.hashCode()+this.age*31;
	}
	//复写equals()方法
	public boolean equals(Object obj){
		if(!(obj instanceof Student))
			return false;
		Student stu=(Student)obj;
		//当两对象姓名年龄都相同时返回true
		return this.name.equals(stu.name)&&this.age==stu.age;
	} 
	//复写compareTo()方法
	public int compareTo(Object obj){
		if(!(obj instanceof Student))
			throw new RuntimeException("不是Student对象");
		Student stu=(Student)obj;
		int num=this.age-stu.age;
		if(num==0)
			return this.name.compareTo(stu.name);
		return num;
	}
	//复写toString()方法
	public String toString(){
		return this.name+"-"+this.age;
	}
}

运行结果:

[aaa-11, aaa-66, ddd-33, ddd-44, kkk-55, xxx-22]
通过结果看出,当为集合传递了比较器后,集合中的元素不再按照元素本身的比较性进行排序,而是按照比较器的方式来进行排序的,所以比较器的优先级要大于元素本身比较性的优先级。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值