——我是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<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;
}
// 重写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<Student> set = new HashSet<Student>();
// 创建学生对象
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<Student> set = new TreeSet<Student>(new Comparator<Student>() {
@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()】这个方法来获取。