您的位置:首页 > 编程语言 > Java开发

JAVA高级应用HashSet与TreeSet应用

2018-01-23 22:11 337 查看

HashSet与TreeSet

HashSet

HashSet添加字符串

特点:无序(无下标)  不重复
linkedHashSet是HashSet的一个子类
特点:有序 不重复 怎么存的就怎么去出来


public static void fun1(){
HashSet<String> set = new HashSet<String>();
boolean b = set.add("a");    //  输出结果为:true
boolean b1 = set.add("a");   //  输出结果为:false
set.add("b");
set.add("b");
set.add("c");
set.add("c");
set.add("d");
set.add("d");

System.out.println(set);  //输出结果:a,b,c,d
}


HashSet添加学生对象去重

package com.lanou3g.set;

public class Person {
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
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 "[姓名=" + name + ", 年龄=" + age + "]";
}

@Override
public boolean equals(Object obj){
Person person = Person(obj);
return this.name.equals(person.getName()) && this.age == person.getAge();
}

@Override
public int hashCode(){
return 1;
}
}


系统在Person类中重写equals方法与hashCode方法

public int hashCode() {
//  31是个质数  只能被1和本身整除  乘法减少公约数

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)  //  如果两个对象地址一样
return true;  //  就返回true
if (obj == null)  //  如果传进来的对象是空
return false; //  就返回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;
}


public static void fun2(){
HashSet<Person> set = new HashSet<Person>();
set.add(new Person("张三",15));
set.add(new Person("张三",15));
set.add(new Person("李四",16));
set.add(new Person("李四",16));
set.add(new Person("王五",17));
set.add(new Person("王五",17));

for(Person person : set){
System.out.println(person);    //结果:去重 从小往大排序
}
}


解释:

set.add()方法自动去重,是因为内部调用了contains()方法,而contains()方法内部又调用了equals()方法,
进行添加的时候,先看对象的hashCode值,不同的对象会有不同的hashCode值,hashCode值不同,默认是两个不同的对象,
而实际进行比较的时候,是看姓名和年龄是否相同,如果相同则认为是同一个对象,为了解决这个矛盾,需要重写hashCode()函数,
使相同姓名与年龄的对象返回的hashCode值一样,在调用hashCode函数后,会调用equals函数,而equals函数比较的是地址,
地址不同,系统也会认为是不同的对象,和现实认为同一对象的情况不符,为了解决这一矛盾,所有要重写equals函数,
在equals函数中比较姓名和年龄,从而通过重写得到与现实情况一致的函数代码.


linkedHashSet

public static void fun3(){
LinkedHashSet<String> set = new LinkedHashSet<String>();
set.add("a");
set.add("1");
set.add("b");
set.add("z");
set.add("a");
System.out.println(set);  //输出结果:a 1 b z
}


解释

这里之所以不重写hashCode()和equals()来去重 ,是因为String是系统类,系统内部已经重写
了equals()方法和hashCode()方法实现去重,不用我们在手动书写


HashSet里面添加Integer对象

//集合长度 < 10 就添加   Integer也重写了HashCode和equals方法
//添加10个1到20之间的随机数
public static void fun4(){
HashSet<Integer> set = new HashSet<Integer>();
while(set.size() < 10){
int num = (int)(Math.random()*(20 - 1 + 1) + 1);
set.add(num);
}
System.out.println(set);
}


输入一个字符串 去掉其中重复字符

public static void fun5(){
HashSet<Character> set = new HashSet<Character>();
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.nextLine();
for(int i = 0; i < str.length(); i++){
char c = str.charAt(i);   //  自动装箱
set.add(c);
}
System.out.println(set);
}


利用set集合 去除ArrayList集合中的重复元素

//  (操作原ArrayList)
public void fun6(){
ArrayList<String> array = new ArrayList<String>();
array.add("a");
array.add("a");
array.add("b");
array.add("b");
array.add("c");
array.add("c");
array.add("d");
array.add("d");

LinkedHashSet<String> set = new LinkedHashSet<String>();
set.addAll(array);
array.clear();
list.addAll(set);
System.out.println(list);
}


TreeSet

特点

无序 不重复 无下标
主要作用:用来排序

使用TreeSet排序的步骤
1.让TreeSet集合中要保存的对象 实现Comparable接口
2.实现compareTo方法
3.在compareTo方法 实现 你要排序的规则


添加方法

public static void fun1(){
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(1);
set.add(2);
set.add(1);
set.add(0);
set.add(8);
set.add(7);

System.out.println(set);   //输出结果:0,1,2,7,8
}


示例1:

//  创建TreeSet集合 保存4个工人
//  系统给你留了接口Comparable 如果你想通过TreeSet来排序
//  你就实现这个接口 编写排序规则 系统就会按规则来排序

实现接口中的唯一的一个方法
/*
* 返回0时    表示两个对象是相同的,set中只有一个元素
* 1(正数)    按存进去的顺序 正序打印
* -1(负数)   按存进去的顺序 倒序打印
*
* TreeSet  按二叉树保存的
* 要保存的数比我大   放在我的右边  (返回负数)
* 要保存的数比我小   放在我的左边  (返回正数)
* 要保存的数一样大   不储存
* 打印按从小到大输出(升序)


class Worker extends Person implements Comparable<Worker>{
public Worker() {
super();
// TODO Auto-generated constructor stub
}

public Worker(String name, int age) {
super(name, age);
// TODO Auto-generated constructor stub
}
@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){
//  不去重
//  比较的主要条件 按年龄
//  次要条件       按姓名
int num = this.getAge() - o.getAge();
return num == 0 ? this.getName().compareTo(o.getName()) : num;
}
@Override
public int compareTo(Worker o){
// 主要比字符串长度
// 然后比年龄
// 最后比较字符串

int length = this.getName().length() - o.getName().length();
int num = length == 0 ? (this.getAge() - o.getAge()) : length;
return num == 0 ? this.getName().compareTo(o.getName()) : num;
}
}


public static void fun2(){
TreeSet<Worker> set = new TreeSet<Worker>();
set.add(new Worker("张三",15));
set.add(new Worker("李四",16));
set.add(new Worker("王五",14));
set.add(new Worker("赵六",17));

//输出方式一:
Susyem.out.println(set);
//输出方式二:
for(Worker work : set){
System.out.println(work);
}
}


比较器

创建比较器来排序
1.创建一个类 实现Comparator接口
2.实现接口中的方法 并 编写 比较的规则
3.把该类的对象 存入TreeSet集合中


示例1

//  保留重复的字符串
//  按字符串长度排序

public static void fun3(){
TreeSet<String> set = new TreeSet<>(new keepString());
set.add("asd");
set.add("wq");
set.add("jjjj");
set.add("qwe");
set.add("a");
System.out.println(set);   //结果:按长度升序排列
}

//实现Comparator接口中compare方法
class keepString implements Comparator<String>{
//  比较的规则
//  主要比较字符串长度
//  次要比字符串
@Override
public int compare(String o1, String o2){
int num = o1.length() - o2.length();
return num == 0 ? o1.compareTo(o2) : num;
}
}


示例2

键盘接收一个字符串, 程序对其中所有字符进行排序
要求保留重复的  使用比较器

public static void fun4(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.nextLine();
TreeSet<Character> set = new TreeSet<>(new keepCharracter());
for(int i = 0; i < str.length(); i++){
set.add(str.charAt(i));
}
System.out.println(set);
}

class keepCharracter implements  comparator<Chararcter>{
@Override
public int compare(Character o1, Character o2){
return o1 > o2 ? 1 : -1;
}
}


示例3

从键盘输入几个整数 进行排序  输入"quit"停止输入
public static void fun5(){
TreeSet<Integer> set = new TreeSet<Integer>(new keepInteger());
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String str = sc.nextLine();
while(!"quit".equals(str)){
int integer = Integer.parse(str);
set.add(integer);
System.out.println("请输入:");
str = scanner.nextLine();
}
System.out.println(set);
}

class keepInteger implements Comparator<Integer>{
@Override
public int compare(Integer o1, Integer o2){
int num = o1 - o2;
return num == 0 ? 1 : num;
}
}


示例4

public class Student implements Comparable<Stdudent>{
private String name;
private int chinese;
private int math;
private int english;
private int sum;
public Student1() {
super();
// TODO Auto-generated constructor stub
}
public Student1(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
sum = chinese + math + english;
}
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;
}

@Override
public String toString() {
return "Student1 [name=" + name + ", chinese=" + chinese + ", math=" + math + ", english=" + english + ", sum="
+ sum + "]";
}

@Override
public int compareTo(Student o){
int num = this.num - o.sum;
return num == 0 ? 1 : num;
}

}

public static void main(String[] args){
TreeSet< Student> set = new TreeSet<>();
Scanner scanner = new Scanner(System.in);
// 循环输入5个学生
while(set.size() < 5) {
System.out.println("录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)");
//  王龙,150,150,150
String string = scanner.nextLine();
//  按逗号切割字符串
String[] strings = string.split(",");
//  把成绩取出来
int chinese = Integer.parseInt(strings[1]);
int math = Integer.parseInt(strings[2]);
int english = Integer.parseInt(strings[3]);

//  构建对象
Student1 student = new Student1(strings[0], chinese, math, english);
//  把对象扔集合中
set.add(student);
}
//  打印一下
System.out.println(set);
}


示例5

public static void main(String[] args) {
//  键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
//  录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
//  王龙,150,150,150
//  按照总分从高到低输出到控制台。输出学生所有信息
TreeSet< Student> set = new TreeSet<>(new KeepStudent());
Scanner scanner = new Scanner(System.in);
for(int i = 0; i < 5; i++) {
Student student = new Student();
System.out.println("请输入 姓名,语文成绩,数学成绩,英语成绩");
String string = scanner.nextLine();
String[] split = string.split(",");

student.setName(split[0]);

Integer integer3 = Integer.parseInt(split[1]);
student.setGrade1(integer3);

Integer integer1 = Integer.parseInt(split[2]);
student.setGrade2(integer1);

Integer integer2 = Integer.parseInt(split[3]);
student.setGrade3(integer2);

set.add(student);
}
System.out.println(set);
}
class keepStudent implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub

int num1= o1.getGrade1() + o1.getGrade2() + o1.getGrade3();
int num2 = o2.getGrade1() + o2.getGrade2() + o2.getGrade3();
int num = num1 - num2;
if(num == 0) {
return 1;
}
return num;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息