Set集合
Set是无序(无下标),不重复的
HashSet
添加字符串:
// 创建一个HashSet
HashSet<String> set = new HashSet<>();
// 添加
boolean add = set.add("d");
boolean add2 = set.add("d");
set.add("a");
set.add("a");
set.add("b");
set.add("c");
System.out.println(add);
System.out.println(add2);
System.out.println(set);
使用HashSet 主要用来 去重
去重:
// 创建一个HashSet 添加6个人
HashSet<Person> set = new HashSet<>();
set.add(new Person("dp", 17));
set.add(new Person("dp", 17));
set.add(new Person("ygs", 18));
set.add(new Person("ygs", 18));
set.add(new Person("sxm", 19));
set.add(new Person("sxm", 19));
Iterator<Person> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
通过重写对象类的 equals 和 hashCode 去重:
当Set集合在进行存储的时候,hashCode值相同时,会调用equals方法进行对比是同一个对象就不存;当hashCode值不相同时 不用调用equals方法,可以直接存
@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;
}
@Override
public boolean equals(Object obj) {
if (this == obj) // 如果两个对象地址一样 返回true
return true;
if (obj == null)// 如果传进来的对象是空 返回false
return false;
if (getClass() != obj.getClass()) // 如果两个对象不是一个类创建出来的
return false; // 就返回 false
Person other = (Person) 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;
}
LinkedHashSet
LinkedHashSet 特点:有序 怎么存就怎么取出来
添加字符串:
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("l");
set.add("w");
set.add("w");
set.add("a");
set.add("n");
set.add("g");
System.out.println(set);
输入一个字符串,去掉其中重复字符
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
LinkedHashSet<Character> set = new LinkedHashSet<>();
char[] charArray = string.toCharArray();
for (int i = 0; i < charArray.length; i++) {
set.add(charArray[i]);
}
System.out.println(set);
利用set集合 去除ArrayList集合中的重复元素(操作原ArrayList)
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("b");
arrayList.add("c");
arrayList.add("c");
LinkedHashSet<String> set = new LinkedHashSet<>();
// 将list所有元素 扔到set中去重
set.addAll(arrayList);
// 清空原arrayList
arrayList.clear();
arrayList.addAll(set);
System.out.println(arrayList);
TreeSet
TreeSet(内部实现二叉树)
特点:无序 不重复
主要作用:排序
代码示例:
// 创建一个TreeSet
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(13);
treeSet.add(1);
treeSet.add(3);
treeSet.add(2);
for (Integer integer : treeSet) {
System.out.println(integer);
}
TreeSet 排序,需要实现Comparable这个接口,编写排序规则,系统就会按规则来排序
compareTo方法:
返回0时 set中只有一个元素
返回1时 按存进去的顺序 正序打印
返回-1时 按存进去的顺序 倒序打印
TreeSet 按二叉树保存的:
要保存的数比根小 放在我的左边
要保存的数比根大 放在我的右边
要保存的数与根一样大 不存
打印 按从小到大输出 (升序)
使用TreeSet排序的步骤:
1.让TreeSet集合中保存的对象 实现Comparable接口
2.实现compareTo方法
3.在compareTo方法中实现你要排序的规则
// 创建TreeSet集合
TreeSet<Worker> treeSet = new TreeSet<>();
treeSet.add(new Worker("sxm0", 11));
treeSet.add(new Worker("sxm01", 11));
treeSet.add(new Worker("sxm5", 12));
treeSet.add(new Worker("sxm4", 12));
treeSet.add(new Worker("sxm2", 15));
treeSet.add(new Worker("sxm3", 14));
for (Worker worker : treeSet) {
System.out.println(worker);
}
// 实现Comparable接口
public class Worker extends Person implements Comparable<Worker>{
public Worker() {
super();
}
public Worker(String name, int age) {
super(name, age);
}
// 实现接口中的唯一方法
// 按年龄比较
@Override
public int compareTo(Worker o) {
return this.getAge() - o.getAge();
}
// 按姓名比较
@Override
public int compareTo(Worker o) {
return this.getName().compareTo(o.getName());
}
// 主要条件 按年龄 次要条件 姓名
@Override
public int compareTo(Worker o) {
if(this.getAge() == o.getAge()) {
return this.getName().compareTo(o.getName());
}
return this.getAge() - o.getAge();
}
// 主要比字符串长度 然后比年龄 最后比字符串
@Override
public int compareTo(Worker o) {
if (this.getName().length() == o.getName().length()) {
if(this.getAge() == o.getAge()) {
return this.getName().compareTo(o.getName());
}
return this.getAge() - o.getAge();
}
return this.getName().length() - o.getName().length();
}
}
Comparator比较器
使用比较器来排序步骤:
1.创建一个类 实现Comparator
2.实现接口中的方法 并编写 比较的规则
3.把该类的对象 传入 TreeSet集合中
比较字符串长度:
TreeSet<String> set = new TreeSet<>(new StringLengthCompareImpl());
set.add("asd");
set.add("asde");
set.add("asdef");
set.add("a");
set.add("asa");
System.out.println(set);
// 创建一个比较器类 专门来做字符串的长度比较
class StringLengthCompareImpl implements Comparator<String>{
// 比较规则
// 主要比 字符串长度
// 次要比 字符串
@Override
public int compare(String o1, String o2) {
int num = o1.length() - o2.length();
return num == 0 ? o1.compareTo(o2) : num;
}
}
保留重复的字符串:
TreeSet<String> set = new TreeSet<>(new KeepStringImpl());
set.add("asd");
set.add("asde");
set.add("asdef");
set.add("a");
set.add("asd");
System.out.println(set);
// 保留重复的字符串 比较器
class KeepStringImpl implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
int length = o1.length() - o2.length();
int num = length == 0 ? o1.compareTo(o2) : length;
// 返回 1 或 -1
return num == 0 ? 1 : num;
}
}