集合2--Set集合及Collections工具类

——我是LGM_Hakka,请多多指教。

Set集合

1、特点

没有重复元素,且无序。

2、常用已实现类

HashSet集合:哈希表结构,不同步,查询速度快。保证元素唯一性的方式依赖于:hashCode()、equals()方法。

TreeSet集合:二叉树结构,不同步,可以对Set集合中的元素进行排序。

3、Set集合中元素的排序

A、元素自身具备自然排序,其实就是实现Comparabe接口重写了compareTo方法。如果元素自身不具备自然顺序,或者具备的自然顺序不是所需的,这时只能用第二种方式。

B、比较器排序,其实就是创建TreeSet集合时,在构造函数中指定具体的比较方式。需要定义一个类实现Comparator接口。重写其中的compareTo方法。再往集合中存储对象时,通常该对象都是需要覆盖hashCode,equals方法的。同时实现Comparable接口,建立对象的自然排序。通常也会重写toString()方法。

4、TreeSet是如何存储数据的

A:把第一个存储进去的数据作为根节点

B:把数据依次和根节点进行比较

比较得到正数往右放

比较得到负数向左放

比较得到0,把后来的数据扔掉

5、从二叉树结构中取数据的内存规则

原则:从每个节点的左边开始,遵循原则  左 中 右

6、实例:

       HashSet集合实例

为了展示的更清晰,在将学生类对象存入集合前,均一个个创建学生对象,没有用匿名对象

class Student implements Comparable {
	// 定义姓名属性
	private String name;
	// 定义年龄属性
	private int age;

	// 无参构造
	public Student() {
	}

	// 带参构造
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	// 获取姓名属性
	public String getName() {
		return name;
	}

	// 设置姓名
	public void setName(String name) {
		this.name = name;
	}

	// 获取年龄
	public int getAge() {
		return age;
	}

	// 设置年龄
	public void setAge(int age) {
		this.age = age;
	}

	// 重写toString方法
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

	// 重写hashCode方法
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	// 重写equals方法
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	// 重写Comparable接口中的compareTo方法
	@Override
	public int compareTo(Student stu) {
		int temp = this.getAge() - stu.getAge();
		return temp == 0 ? stu.getName().compareTo(this.getName()) : temp;
	}

}
// ---------------------------------------------
import java.util.HashSet;
import java.util.Set;

public class StuHashSet {
	public static void main(String[] args) {
		// 创建HashSet对象
		Set set = new HashSet();

		// 创建学生对象
		Student s1 = new Student("张三", 22);
		Student s2 = new Student("李四", 23);
		Student s3 = new Student("王五", 25);
		Student s4 = new Student("李四", 23);

		// 将学生对象存储到HashSet集合中
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);

		// 遍历集合
		for (Student s : set) {
			System.out.println("姓名:" + s.getName() + "\t年龄:" + s.getAge());
		}
	}
}

TreeSet实例

为了展示的更清晰,在将学生类对象存入集合前,均一个个创建学生对象,没有用匿名对象

class Student {
	// 定义姓名属性
	private String name;
	// 定义年龄属性
	private int age;

	// 无参构造
	public Student() {
	}

	// 带参构造
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	// 获取姓名
	public String getName() {
		return name;
	}

	// 设置姓名
	public void setName(String name) {
		this.name = name;
	}

	// 获取年龄
	public int getAge() {
		return age;
	}

	// 设置年龄
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	// 重写toString方法
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	// 重写hashCode方法
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	// 重写equals方法
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

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

public class StuTest {
	public static void main(String[] args) {
		// 创建TreeSet集合对象,并通过匿名对象,进行排序
		Set set = new TreeSet(new Comparator() {
			@Override
			public int compare(Student o1, Student o2) {
				int temp = o1.getAge() - o2.getAge();
				return temp == 0 ? o1.getName().compareTo(o2.getName()) : temp;
			}
		});

		// 创建学生对象
		Student s1 = new Student("lgm", 22);
		Student s2 = new Student("lxn", 16);
		Student s3 = new Student("lsh", 21);
		Student s4 = new Student("wyp", 20);
		Student s5 = new Student("lgm", 22);
		Student s6 = new Student("lgm", 23);
		// 将学生对象存入集合中
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		set.add(s6);

		//遍历集合
		for (Student s : set) {
			System.out.println(s);
		}
	}
}

Collections工具类

1、为了解决集合的更多需求。集合框架提供了Collections工具类,方法都是静态的。所以,可以通过类名.方法名直接调用。

2、Collections是用于操作集合的工具类。

常见方法:对List集合排序,二分查找,对Collection集合进行最值获取。对排序进行逆序等。

3、Collection和Collections的区别?【面试题】

Collection是Collection体系的顶层接口, 里面定义了这个体系中的共性方法。

Collections是针对Collection集合操作的工具类里面一定了一些对集合操作的方法。比如:排序、查找、反转、最值、置换等等。

 

集合和数组相互转换的目的

数组转换为集合的目的

为了使用集合的方法操作数组中元素。

A、数组的长度是固定的,所以转成List集合的长度也是固定的。

B、不要使用增删等改变长度的方法。例如:add,remove等。否则会发生异常。UnsupportedOperationException

C、如果数组中存储的是基本数据类型时,那么转成集合,数组对象回作为集合中的元素存在。

D、如果数组中存储的是因用户数据类型时,那么转成集合,数组元素会作为集合元素存在。

 

集合转换为数组的目的

为了限制对元素的增删操作。

A、如果传递的数组的长度小于集合的长度时,会自动创建一个同类型的数组长度为集合长度的数组。

B、如果传递的数组的长度大于集合的长度时,就会使用这个数组,没有存储元素的位置为null。

C、长度最好直接定义为集合的长度。集合的长度可以通过【集合名.size()】这个方法来获取。

你可能感兴趣的:(Java,SE)