目录
HashSet存储字符串并遍历
hashset是通过哈希表支持,他不保证set的迭代顺序,特别是不保证该顺序恒久不变,此类允许添加NULL元素
import java.util.HashSet;
public class demo {
//set集合,无索引,不可以重复,无序(存取不一致)
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<String> hs = new HashSet<>();
boolean b1= hs.add("a");
boolean b2= hs.add("a"); //当向set集合中存储重复元素的时候返回为false
hs.add("b");
hs.add("c");
hs.add("d");
System.out.println(b1); //true
System.out.println(b2); //false
System.out.println(hs); //HashSet的继承体系中有重写toString方法
for(String string :hs) {
System.out.println(string); //只要能用迭代器迭代的就能使用增强for循环遍历
}
}
}
HashSet存储自定义对象保证元素的唯一性
import java.util.HashSet;
import com.P.Person;
public class demo1 {
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<>();
hs.add(new Person("张三",23));
hs.add(new Person("张三",23));
hs.add(new Person("李四",23));
hs.add(new Person("李四",23));
hs.add(new Person("李四",23));
System.out.println(hs); //全部都存储进来,由于对象的地址值不同
//重写Person中的hashcode()以及equals()
}
}
由于HashCode()通过对象地址值来计算出值,然后再决定改对象存储在什么位置,需不需要进equals方法,由于地址值一直都不一样,因此直接不调用equals方法。所以要重写hashcode()以及equals()方法。
如下
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
return age == other.age && Objects.equals(name, other.name);
}
HashSet如何保证元素唯一性原理
我们使用Set集合都是需要去掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals()方法的次数
当HashSet()调用add()方法存储对象时,先调用对象的HashCode()方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象
如果没有哈希值相同的对象就直接存入集合
如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入,true就不存入
将自定义类的对象存入HashSet去重复
类中必须重写hashcode()和equals()方法
hashcode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同
equals():属性相同返回true,属性不同返回false,返回false时存储
LinkedHashSet的概述
底层是用链表实现的,属于HashSet()派系,是set集合中唯一一个能保证怎么存就怎么取的集合对象,也是保证元素唯一的,与hashset()的原理一样
产生10个1-20之间的随机数要求随机数不能重复
import java.util.HashSet;
import java.util.Random;
public class test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Integer> hs = new HashSet<>(); //存储于hashset中
Random r = new Random(); //用random()生成随机数
while(hs.size()<10) { //如果集合里面存储的数字不到十个就继续存进去
hs.add(r.nextInt(21)); //生成随机数并存进集合
}
// System.out.println(hs);
for(Integer integer : hs) { //用增强for遍历集合
System.out.println(integer);
}
}
}
练习
用Scanner从键盘读取一行输入,去掉其中重复字符,打印出不同的字符
import java.util.HashSet;
import java.util.Scanner;
public class test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in); //创建scanner对象
HashSet<Character> hs = new HashSet<>(); //创建hashset集合
String line = sc.nextLine(); //输入字符串存入line中
char[] arr = line.toCharArray(); //利用String中的方法将字符串转成字符数组
for(int i=0;i<arr.length;i++) { //遍历数组将数字存在集合中
hs.add(arr[i]);
}
System.out.println(hs);
}
}
将集合中的重复元素去掉
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class test3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> al = new ArrayList<>(); //创建集合
al.add("a"); //添加元素
al.add("ad");
al.add("a");
al.add("ad");
al.add("a");
al.add("ad");
getSingle(al); //创建方法去除重复
System.out.println(al); //打印集合
}
public static void getSingle(List<String> al) {
// TODO Auto-generated method stub
LinkedHashSet<String> lhs = new LinkedHashSet<>(); //创建set集合
for(String string : al) { //利用增强for循环将 list集合中的东西存入set集合中,重复元素不会被存进去
lhs.add(string);
}
al.clear(); //将原list集合清楚
for(String string : lhs) { //将set集合中的元素再添加进原集合中
al.add(string);
}
}
}
TreeSet存储integer类型的元素并遍历
TreeSet集合是用来对象元素进行排序的,同时他也可以保证元素的唯一性
import java.util.TreeSet;
public class demo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Integer> ts = new TreeSet<>();
ts.add(3);
ts.add(2);
ts.add(1);
ts.add(3);
ts.add(1);
ts.add(2);
System.out.println(ts);
}
}
TreeSet存储自定义对象
import java.util.TreeSet;
import com.P.Person;
public class demo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Person> ts =new TreeSet<>();
ts.add(new Person("张三",23));
ts.add(new Person("王五",25));
ts.add(new Person("李四",24));
//需要在person类中实现comparable
//当compareto方法返回0时,集合中只有一个元素
//返回正数时,怎么存怎么取
//返回负数时,集合会倒叙存储
System.out.println(ts);
}
}
底层是利用二叉树存储的
小的存储在左边(返回负数),大的存储在右边(正数),相等就不存(0)
compareto方法,在treeset集合如何存储元素取决去compareto方法的返回值
因此compareto重写应该如下
按照年龄排序
public int compareTo(Person o) {
// TODO Auto-generated method stub
int num = this.age-o.age;
return num==0 ?this.name.compareTo(o.name):num;
}
按照姓名排序( 姓名比较的是unicode码表值
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
int num = this.name.compareTo(o.name);
return num == 0 ? this.age - o.age :num;
}
按照姓名长度排序
public int compareTo(Person o) {
int length = this.name.length() - o.name.length();
int num = length == 0? this.name.compareTo(o.name):length;
return num == 0 ? this.age - o.age : num;
}
TreeSet保证元素唯一和比较器排序的原理以及代码实现
import java.util.TreeSet;
public class demo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<String> ts =new TreeSet<>(new CompareByLen()); //Comparator c = new CompareByLen()
ts.add("qw");
ts.add("werfd");
ts.add("as");
//默认按照字典顺序排序
System.out.println(ts);
}
}
class CompareByLen /*extends Object*/ implements Comparator<String> {
@Override
public int compare(String o1, String o2) { //按照字符串的长度比较
int num = o1.length() - o2.length();
return num == 0 ? o1.compareTo(o2) : num;
}
//由于默认继承了Object类因此相当于已经有了一个equals方法,因此实现comparator接口里面只需要重写compare
}
TreeSet原理
TreeSet是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列
使用方式:
自然顺序:
TreeSet类的add()方法中会把存入的对象提升为Comparable
调用对象的compareTo()方法和集合中的对象比较
根据compareTo()方法返回的结果进行存储
比较器顺序:
创建TreeSet的时候可以制定一个Comparator
如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序
add()方法内部会自动调用Comparator接口中的compare()方法排序
两种方式的区别:
TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报错classCastException
TreeSet如果传入comparator就优先comparator
练习
输入几个字符串,其中有重复字符串,使其按照字典顺序输出
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
public class dd {
/*
* 定义list集合存储
* 定义方法对其排序
* 打印list集合
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> ts = new ArrayList<>();
ts.add("aaa");
ts.add("aaa");
ts.add("aaa");
ts.add("gvhc");
ts.add("xnc");
ts.add("ach");
sort(ts);
for(Character c : al){
System.out.print(c);
}
}
public static void sort(List<String> list){
//本身具有排序功能但是会去除重复,因此需要使用比较器
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() { //匿名内部类
@Override
public int compare(String s1, String s2) {
int num = s1.compareTo(s2);
return num == 0 ? 1 :num;
}
});
ts.addAll(list);
list.clear();
list.addAll(ts);
}
}
键盘接收一个字符串,程序对其所有的字符进行排序,例如键盘输入:helloitcast程序打印acehillostt
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class test2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] arr = s.toCharArray();
ArrayList<Character> al = new ArrayList<>();
for(char c :arr){
al.add(c);
}
sort(al);
System.out.println(al);
}
public static void sort(ArrayList<Character> list){
TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
int num = o1.compareTo(o2);
return num == 0 ? 1 :num ;
}
});
ts.addAll(list);
list.clear();
list.addAll(ts);
}
}
程序启动后,可以从键盘输入接收多个整数,知道输入quit时输入结束,把所有输入的整数倒序排列打印
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class test3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int num = o1.compareTo(o2);
return num == 0 ? 1 : num;
}
});
while(true) {
String s = sc.nextLine();
if(s.equals("quit")){
break;
}
else {
Integer i = Integer.parseInt(s);
ts.add(i);
}
}
for(Integer i :ts){
System.out.println(i);
}
}
}
键盘录入五个学生信息按照总分排序后输出在控制台
import student.Student;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class test4 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生的成绩");
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int num = o1.getScore()-o2.getScore();
return num == 0 ? 1 :num;
}
});
while(ts.size() < 5) {
String s =sc.nextLine();
String[] arr = s.split(",");
int age = Integer.parseInt(arr[1]);
int score = Integer.parseInt(arr[2]);
ts.add(new Student(arr[0],age,score));
}
for(Student s : ts){
System.out.println(s);
}
}
}