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; } }
相关文章推荐
- Java多线程与并发库高级应用-传统线程互斥技术
- Java 执行系统命令的高级应用.
- 张孝祥_Java多线程与并发库高级应用04
- Java线程与并发库高级应用-线程范围内共享数据ThreadLocal类
- JAVA高级应用之集合 迭代器
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
- Java多线程与并发库高级应用-工具类介绍
- JavaEE ActionForm的高级应用
- Weka高级应用--Java API
- java高级进阶关于java多线程的应用 ThreadLocal多线程实例详解
- java多线程并发库高级应用 之 java5中的线程并发库--线程池、Callable&Future
- Java多线程与并发库高级应用
- mongodb高级操作及在Java企业级开发中的应用
- 深入Java基础(四)--哈希表(2)HashTable与HashSet应用及源码详解
- spark自定义Accumulator高级应用(JAVA)
- 多线程并发库高级应用 之 java5中的线程并发库--线程池、Callable&Future
- 多线程并发库高级应用 之 使用java5中同步技术的3个面试题
- Java反射高级应用--利用反射调用类的私有方法修改私有方法值,以及替换Java的类成员数据