Set集合
特点:无序 无重复
存储自定义的元素,要重写hashCode和equals方法
(先比较hashCode值,如果hashCode的值是相同的话,就调用equals方法),如果hashCode的值值是相同的情况之下,就会按照hash桶的方式实现。
代码:
import java.util.Objects;
/**
* @author kiosk
*/
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//
// public int hashCode() {
// //也有可能出现hashCode值相同的情况,尽量让hashCode的值不同,
// // 但是实际的开发中不用我们自己手写hashCode的代码
// return name.hashCode() + age;
// }
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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;
}
}
/**
* set集合中存储自定义的对象
* 不但要重写equals方法还要重写hashCode方法
* @author kiosk
*/
public class Test2 {
public static void main(String[] args) {
HashSet<Person> set = new HashSet<>();
set.add(new Person("张三",23));
set.add(new Person("李四",24));
set.add(new Person("张三",23));
set.add(new Person("张三",23));
set.add(new Person("张三",23));
set.add(new Person("张三",23));
System.out.println(set.size());
System.out.println(set);
}
}
hashCode方法使用31的原因
(1)31为一个质数,造成hashCode值相同的情况是很小的
(2)31不大也不小,不会超过int的范围
(3)31计算简单 2的5次方-1 将2左移五位
hashCode的方法降低了equals方法的使用的次数,提高了效率。如果hashCode值相同时候就会调用equals方法如果返回的值为true就不存,如果为false就存入。
LinkedHashSet
import java.util.LinkedHashSet;
/**
* LinkedHashSet集合使用链表实现的
* 特点:元素唯一 元素是有序的
* @author kiosk
*/
public class TestLinkedHashSet {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("hello");
set.add("java");
set.add("world");
set.add("world");
for (String s : set) {
System.out.println(s);
}
System.out.println(set);
}
}
产生1-20 的随机数并进行存储
采用hashSet来存储
/**
* 产生10个 1-20的随机数
* @author kiosk
*/
public class TestRandom {
public static void main(String[] args) {
Random random = new Random();
HashSet<Integer> set = new HashSet<>();
while (set.size() < 10){
set.add(random.nextInt(20) + 1);
}
for (Integer integer : set) {
System.out.println(integer);
}
}
}
从键盘录入字符然后将输入的字符去除重复,然后将去除后的打印出来
import java.util.HashSet;
import java.util.Scanner;
/**
* 从键盘中输入字符,然后将重复的符号删除
*
* @author kiosk
*/
public class TestKeyboard {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一串字符");
HashSet<Character> set = new HashSet<>();
String line = scanner.nextLine();
char[] chars = line.toCharArray();
for (char ch : chars) {
set.add(ch);
}
//自动装箱
for (Character character : set) {
System.out.println(character);
}
}
}
用来将List集合中重复的元素去除
import java.util.*;
/**
* 将集合中的重复的元素去掉
* 新建一个List集合,存储重复的元素
* 单独的定义一个方法去除重复
* 遍历打印集合
* @author kiosk
*/
public class Test3 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("world");
list.add("world");
list.add("world");
list.add("java");
list.add("java");
list.add("linux");
List<String> single = getSingle(list);
for (String s : single) {
System.out.println(s);
}
}
/**
* 用来去除重复
* 分析:去除重复? 1)创建一个LinkedHashSet 2)将LinkedList中的元素
* 添加进LinkedHashSet 3)将LinkedList中的元素清除
* 4)将LinkedHashSet中的元素添加进LinkedList中
* @return
*/
public static List<String> getSingle(List<String> list){
//创建一个 LinkedHashSet
LinkedHashSet set = new LinkedHashSet();
//将list中的元素添加进LinkedHashSet中,用来去重
set.addAll(list);
// 将原来的list中的元素进行清除
list.clear();
//然后将LinkedHashSet中的数据添加进来
list.addAll(set);
return list;
}
}
TreeSet
(1)存储自定义的对象,要实现Comparable接口,并重写compareTo方法
返回值为0的话:只有一个元素
返回值为正数的话:怎么存就怎么取
返回值为负数的话:倒序
底层数据结构:二叉树,小的在左边(负数)大的在右边(正数)相等(0)
@Override
public int compareTo(Person o) {
System.out.println("compareTo方法执行了");
int age = this.age - o.age;
int name = this.name.compareTo(o.name);
return age == 0 ? name : age;
}
/**
* TreeSet用来存储自定义的类
* @author kiosk
*/
public class TestTreeSet2 {
public static void main(String[] args) {
TreeSet<Person> set = new TreeSet<>();
set.add(new Person("王五",22));
set.add(new Person("赵六",34));
set.add(new Person("张三",44));
set.add(new Person("王五",21));
for (Person person : set) {
System.out.println(person);
}
}
}
@Override
public int compareTo(Student o) {
//先比较的是姓名的长度,之后比较的是行吗内容,之后比较的是年龄
int num = this.name.length() - o.name.length();
int num2 = num == 0 ? this.name.compareTo(o.name) : num;
return num2 == 0 ? this.age - o.age : num2;
}
(2)第二种比较器的写法
import java.util.Comparator;
/**第二种比较器的写法
* @author kiosk
*/
public class Mycompare implements Comparator<Teacher> {
@Override
public int compare(Teacher o1, Teacher o2) {
//先比较的是名字的长度
int num = o1.getName().length() - o2.getName().length();
//
int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;
return num2 == 0 ? o1.getAge() - o2.getAge() : num2;
}
}
测试
/**
* @author kiosk
*/
public class TestTreeSet3 {
public static void main(String[] args) {
TreeSet<Teacher> set = new TreeSet<>(new Mycompare());
set.add(new Teacher("jackwwww",20));
set.add(new Teacher("rose",11));
set.add(new Teacher("james",40));
for (Teacher teacher : set) {
System.out.println(teacher);
}
}
}
键盘中输入一串字符,然后进行排序但是不要求去重
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* 从键盘中输入的字符串进行排序,但是不进行去重操作
* @author kiosk
*/
public class Test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请您输入一串字符");
String line = scanner.nextLine();
String sort = sort(line);
System.out.println(sort);
}
public static String sort(String line){
char[] chars = line.toCharArray();
TreeSet<Character> set = new TreeSet<>(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
int num = o1.compareTo(o2);
return num == 0 ? 1 : num;
}
});
for (char aChar : chars) {
set.add(aChar);
}
StringBuilder builder = new StringBuilder();
for (Character character : set) {
builder.append(character);
}
return builder.toString();
}
}
对键盘输入的正数反向打印
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* 键盘中输入多个整数,直到输入quit时,就进行反向的打印
*
* @author kiosk
*/
public class Test3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//降序操作
int num = o2 - o1;
return num == 0 ? 1 : num;
}
});
while (true) {
String line = scanner.nextLine();
if("quit".equals(line)){
break;
}
set.add(Integer.valueOf(line));
}
for (Integer integer : set) {
System.out.println(integer);
}
}
}
将输入的学生的成绩按照总分进行排序
/**
* @author kiosk
*/
public class Student2 {
private String name;
private int chinese;
private int math;
private int english;
private int sum;
public Student2() {
}
public Student2(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
this.sum = this.chinese + this.math + this.english;
}
public int getSum() {
return this.sum;
}
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", math=" + math +
", english=" + english +
", sum=" + sum +
'}';
}
}
/**
* @author kiosk
*/
public class Test4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生的成绩");
TreeSet<Student2> set = new TreeSet<>(new Comparator<Student2>() {
@Override
public int compare(Student2 o1, Student2 o2) {
int num = o1.getSum() - o2.getSum();
return num == 0 ? 1 :num;
}
});
while (set.size() <= 2){
System.out.println(set.size());
String line = scanner.nextLine();
String[] strings = line.split(",");
int chinese = Integer.valueOf(strings[1]);
int math = Integer.valueOf(strings[2]);
int english = Integer.valueOf(strings[3]);
set.add(new Student2(strings[0],chinese,math,english));
}
System.out.println(set);
}
}