特点:无序(没有下标) 不重复
子类: HashSet : 去重的功能; LinkedHashSet:表示的是有序的;
TreeSet: 有自己独特的方法:排序的功能
HashSet 在存放对象的时候会判断对象是不是同一个对象 .
1. 默认引用类型比较的是地址值,如果地址相同,name这是一模一样的对象,将不再重复往里面放.
2 . 如果对象 重写了hashcode和equals放法,就比较这两者是否相等.
如果hashcode相等,那么比较的是equals方法,如果equals再相等,那么证明这是同一个对象,如果equals不相等,
那么即使hashcode相等,也是两个对象.
3.HashSet已经重写了父类的equals和hashcode方法;
注意:equals和 == 区别!
简单的说,“==”用于判断引用是否相等,equals()用于判断值是否相等
public static void main(String[] args) {
String a = new String("abc");
String b = new String("abc");
System.out.println(a==b);//结果为false
System.out.println(a.equals(b));//结果为true
}
例题:1. 创建一个HashSet 2. 保存 f f a a b b;(在系统类中操作去重)
只要创建对象,就会给没一个对象分配一个hashcode; hashcode 如果不同就不会调用equals .
HashSethash = new HashSet();
hash.add("f");
hash.add("f");
hash.add("a");
hash.add("a");
hash.add("b");
hash.add("b");
//迭代器遍历
Interator iterator=hash.iterator();
while(iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
//或者增强for 循环进行遍历
for (String string : hash){
System.out.println(string);
}
}
1. 自己创建一个Person类;创建一个集合保存6个Person;并且要去去重.
HashSet set = new HashSet<>();
set.add(new Person("张三"),12);
set.add(new Person("张三"),12);
set.add(new Person("张四"),13);
set.add(new Person("张四"),13);
set.add(new Person("张五"),14);
set.add(new Person("张五"),14);
//遍历集合
for(Person person:set){
System.out.println(set)
}
//想要获得的打印结果,需要重写Person的hashCode 和equals方法;
Person [name=张三, age=12]
Person [name=张四, age=13]
Person [name=张五, age=14]
2.创建一个Person类;
public class Person implements Comparable {//这里实现comparable是为了下面用TreeSet排序; 在下面3中例题3里面有体现;
private String name ;
private int 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 + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
//因为上面创建的集合要进行除重操作,这时父类的去重方法不再适用(父类==比较的是地址),我们需要重写hashCode和equals方法;
public int hashCode(){
//这里如果过返回值是一样的,默认两个对象是一样的;这里返回值我们和两个成员变量进行联系
return this.name.hashCode() + this.age;
}
//重写equals方法
public boolean equals (Object object){
Person p = (Person) object;
//如果字符串(name) 一样并且年龄的数值一样,那么这两个对象就是一样的这样我们就可以进去重了;
return this.name.equals(p.name)&&this.getAge==p.getAge()
}
}
public int compareTo(Person o) { //此处重写了接口compareble中的 compareTo方法;
// TODO Auto-generated method stub
//按照年龄排序,如果是int 直接相减;
//return (this.age) - (o.getAge());
//按照姓名比较需要使用字符串compare"To进行比较 返回int值点进去看;
//return this.name.compareTo(o.getName());
int num = this.age -o.getAge();
//这时啥意思;
return num==0?this.name.compareTo(o.getName()):num;
}
3.利用set集合 去除ArrayList集合的重复元素; ArraysList里面保存着 a a b b c c d d ;
ArrayList list = new ArrayList();
list.add("a")
list.add("a")
list.add("b")
list.add("b")
list.add("c")
list.add("c")
//创建HashSet集合接收一下,顺便去重
HashSet set = new HashSet();
set.addAll(list); //将list集合里面的元素全部放到set里面去
list.clear(); //清空list
list.addAll(set); //再将处理好的数据放回到list 里面;
//增强for循环;遍历
for(String string: list)
4.编写一个程序,获取10个 1 -20的随机数,要去随机数不能重复 1.创建一个set 2. 循环生成10个数 3. 添加到set中去;
HashSet set = new Integer();
while(set.size()<10){
int rd = (int)(Math.random()*(20-1+1)+1);
//循环往集合里面添加数据;
set.add(rd);//这里系统自动装箱,可一直接传入int类型的数字;
}
//打印集合长度
System.out.println(Hash.size());
打印这个集合;
System.out.println(set);
TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用自然排序。
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系.然后将集合元素按升序排列,这种方式就是自然排序。(比较的前提:两个对象的类型相同)。
1.主要有两种方式
方式1: 1. Object实现comparable接口,可以重写compareTo方法; 2. 实现接口中的compareTo()方法; 3. 编写你想要的排序规则;(自己创建的类)在类里面
方式2: 1. 系统类 : (comparator)比较器. 1 创建比较器, 在创建一个是实现接口的实现类,重写compare()方法再将
实现类创建的一个对象,放入到 new TreeSet( new 对象);
两种重写方法返回值都是 int 类型;
1 . 创建一个TreeSet集合添加几个数,查看是如何排序的;(Integer比较的是数值的大小)
TreeSet(Integer)set = new TreeSet();
set.add(6);
set.add(3);
set.add(3);
set.add(7);
set.add(5); System.out.println(set);//打印结果 [3, 5, 6, 7] //去重并且排序了;
2. 例题: 创建一个TreeSet集合,集合中保存的是字符串,按照字符串的长度进行排序,(这里使用的是系统类;)
这里我们需要重写比较规则,需要创建一个比较器(comparator),然后找个实现比较器的类,最后在初始化TreeSet对象的时候
将该实现类传进去;
2 : 创建一个类实现(接口comparator)中的Compara()方法;
public class StringLengthImpl implements
Comparator {
//实现比较器中的方法;
public int compare(String o1,String o2){
//如果两个字符串长度不一样.直接返length;
//字符串长度进行对比;返回值length
int length = o2.length- o1.length;
//如果长度相等要比较每一位了;
int num1= o2.compareT(o1);
//用判断语句接收上面返回的结果
int rel = length==0?num1:length;
//最终判断,就算相等也不能赋值0.0会默认去重;
return rel == 0 ?1:rel
}
}
注意:比较规则:
//自己创建的类要实现是comparable接口,要重写抽象方法; public int compareTo() { }
//返回0的时候:只有一个元素; //所以我们不能让他返回零
//返回正数的时候:打印数据 正序输出;
//返回负数的时候;打印的数据 倒序输出;
//TreeSet 二叉树
//比我小的数值放到我的左边(返回负数的情况);
//比我大的数值放到我的右边(返回正数的情况);
//如果你返回的是零就不存储,
//集合中保存字符串,按照字符串长度排序;
//使用比较器来进行排序;
//在比较器中写你的比较规则;
//利用TreeSet的构造方法 直接将比较器的实现类传进去;
TreeSet set = new TreeSet<>(new StringLengthImpl());//此处传入实现类;
set.add("wanglong");
set.add("kun");
set.add("huxin");
set.add("zhangjianhai");
System.out.println(set);//打印一下就知道有没有实现comparable接口
例题3: 添加五个人( Person )然后进行排序;
TreeSet set = new TreeSet<>();
set.add(new Person("张三",11));
set.add(new Person("张4", 12));
set.add(new Person("张5", 13));
set.add(new Person("张6", 14));
System.out.println((int)'张');
System.out.println((int)'三');
System.out.println(set);
例题4: 排序而且不用去重复(用比较器) 2. 主要按照字符串进行比较,次要按照字符进行比较;
首先: 使用比较器;
class StringLengthImpl implements Comparator {
// 实现比较器方法;
@Override
public int compare(String o1, String o2) {
// 实现比较器规则长度比较;
int length = o1.length() - o2.length();
// 字符串比较
int num1 = o1.compareTo(o2);
int rel = length == 0 ? num1 : length;
return rel == 0 ? 1 : rel;
}
}
private static void 排序2() {
// 要求: 排序,而且还不能去除重复(用比较器)
// 主要按字符串长度比较 次要按字符串字符比
ArrayList set = new ArrayList<>();
set.add("wanglong");
set.add("wanglong");
set.add("kun");
set.add("huxin");
set.add("zhangjianhai");
//将接口传进去;
TreeSet set1 = new TreeSet<>(new StringLengthImpl());
set1.addAll(set);
set.clear();
set.addAll(set1);
System.out.println(set1);
}
例题5: 键盘输入一个字符串,程序对其中所有的字符进行排序.要求保留重复的.
//char比较器
class CharLengthImp implements Comparator{
@Override
public int compare(Character o1, Character o2) {
int num = o1.compareTo(o2);
//等于零不能删除,等于num判断正负
return num==0 ?1:num;
}
}
System.out.println("请输入一个字符串");
Scanner scanner = new Scanner(System.in);
String string= scanner.nextLine();
//字符串转换成字符数组;toCharArray();
char[] array = string.toCharArray();
//创建排序的集合
TreeSet set = new TreeSet<>(new CharLengthImp());
//将字符数组中的字符添加到Set中;
for (int i = 0; i < array.length; i++) {
//将字符数组每一项穿进去;
set.add(array[i]);
}
System.out.println(set);
class NumberCompare implements Comparator{
@Override
public int compare(Integer o1, Integer o2) {
int num = o1-o2;
//如果等于零返回1,否则返回num;
return num ==0 ? 1 : num;
//在构造中加入;
}
}
System.out.println("请输入整数 quit 时候结束;");
Scanner scanner = new Scanner(System.in);
TreeSet set = new TreeSet<>(new NumberCompare());
while (true) {
// 接收用户输入;
String string = scanner.nextLine();
// 判断是不是quit
if (string.equals("quit")) {
break;
}
// 转化成数字;
int num = Integer.parseInt(string);
// 保存到集合中排序;
set.add(num);
}
System.out.println(set);
例题7:
/* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
按照总分从高到低输出到控制台。输出学生所有信息*/
//创建set保存学生;
创建学生类:
public class Student implements Comparable {
private String name;
private int chinese;
private int math;
private int english;
private int sum;
public Student(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
this.sum = chinese + math + english;
}
@Override
public String toString() {
return "Student [name=" + name + ", chinese=" + chinese + ", math=" + math + ", english=" + english + ", sum="
+ sum + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
//在类中实现
@Override
public int compareTo(Student o) {
int num = this.sum-o.getSum();
return num==0?1:num;
}
}
private static void fun7键盘输入数字打印结果() {
/* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
按照总分从高到低输出到控制台。输出学生所有信息*/
//创建set保存学生;
TreeSet set = new TreeSet<>();
Scanner scanner = new Scanner(System.in);
//循环五次;
while (set.size()<5) {
System.out.println("请输入学生成绩按照格式姓名,语文成绩,数学成绩,英语成绩");
//接收用户输入 王龙,150,150,150;
String string = scanner.nextLine();
//切割字符串;
String[] strings = string.split(",");
//从数组中取出数据
String name= strings[0];
int chinese = Integer.parseInt(strings[1]);
int math = Integer.parseInt(strings[2]);
int english = Integer.parseInt(strings[3]);
//创建学生对象;
Student student = new Student(name, chinese, math, english);
//添加到Set中;
set.add(student);
}
//遍历集合
for (Student student : set) {
System.out.println(student);
}
}