1、集合框架Set
特点:元素是无序(存入和取出的顺序不一定一致),
元素不可以重复(针对于基本数据类型和String);
代码如下:
package com.zhuyuncong.set;
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set set=new HashSet<>();
set.add("aa");
set.add("bb");
set.add("cc");
set.add("dd");
set.add("aa");
System.out.println(set.size());
}
}
结果:
2、集合框架hashset
HashSet哈希表存储
底层数据结构是哈希表
什么是哈希表?
在ArrayList中每new一个对象都会创建一个新的地址。
而哈希表把整个内存当做一个表,进行分层。
哈希表如果增加一个相同属性的对象时,首先对比的
是hashCode值,如果俩个对象的hashCode值相同,
就会调用equals方法进行比较。
如下代码(Set去重)
package com.zhuyuncong.set;
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set set=new HashSet<>();
// set.add("aa");
// set.add("bb");
// set.add("cc");
// set.add("dd");
// set.add("aa");
set.add(new Person("aa",18));
set.add(new Person("bb",22));
set.add(new Person("cc",21));
set.add(new Person("dd",18));
set.add(new Person("aa",18));
System.out.println(set.size());
}
}
class Person{
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
super();
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
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
};
@Override
public int hashCode() {
// TODO Auto-generated method stub
System.out.println("调用hashCode:"+this.getName());
return this.getName().hashCode() + this.age;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(obj instanceof Person) {
Person p=(Person)obj;
System.out.println(this.getName()+"---equals---"+p.getName());
return this.getName().equals(p.getName()) && this.getAge() == p.getAge();
}
return false;
}
}
结果:
3、集合框架TreeSet
特点:自然排序(自动通过字母顺序进行排序)、数据结构二叉树
TreeSet会对String类型数据进行排序,但不能对自定义对象进行排序
TreeSet对引用对象排序的俩种方式
1、实现Comparable接口,让元素具有比较性
代码如下
class Person implements Comparable<Person>{}
/**
* 本方法用来定义排序的规则
* 正数:代表后面的比前面的大
* 0:后面的与前面的相等
* 负数:后面的比前面的小
* this代表还没有存放到容器中的对象
* o代表已经在容器中的对象
* this代表后面的对象,o代表前面的对象
*/
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return this.getAge() - o.getAge();
}
package com.zhuyuncong.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo{
public static void main(String[] args) {
TreeSet ts=new TreeSet<>();
ts.add(new Person("aa",18));
ts.add(new Person("bb",22));
ts.add(new Person("cc",21));
ts.add(new Person("dd",18));
ts.add(new Person("ee",19));
Iterator it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
运行以下代码结果:
由此可见,这是按照年龄进行升序,而dd的年龄与aa的一致,所以没有展示
因此,我们要在compareTo方法里先判断年龄,如果年龄相等,再判断名字
代码如下:
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
int num= this.getAge() - o.getAge();
if(num == 0) {
return this.getName().compareTo(o.getName());
}
return num;
}
再次运行的结果为:
注意:在给元素添加比较性的时候,先判断主要条件(age),在判断次要条件(name)
2、实现comparator接口,让容器具有比较性
代码如下:
class PersonComp implements Comparator<Person>{}
再重新运用:
package com.zhuyuncong.set;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo{
public static void main(String[] args) {
// TreeSet ts=new TreeSet<>();
TreeSet ts=new TreeSet<>(new PersonComp());
ts.add(new Person("aa",18));
ts.add(new Person("bb",22));
ts.add(new Person("cc",21));
ts.add(new Person("dd",18));
ts.add(new Person("aa",19));
Iterator it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class PersonComp implements Comparator<Person>{
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
int num = o1.getName().compareTo(o2.getName());
if(num == 0) {
return o1.getAge() - o2.getAge();
}
return num;
}
}
结果如下:
由此可见,当前的主要条件为name,次要条件为age。