HashSet底层原理
哈希表的组成
哈希值
Object类的API
对象的哈希值特点
HashSet 1.7版本原理解析:数组+链表+哈希算法
【JDK 7新元素占老元素位置,指向老元素】
【JDK 8中新元素挂在老元素下面(链表形式)】
哈希表是一种对于增删改查数据性能都较好的结构
HashSet 1.8版本原理解析
Student
public class Student {
private String name;
private Integer age;
private char sex;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return sex == student.sex && Objects.equals(name, student.name) && Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Student(String name, Integer age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public Student() {
}
}
public class Test {
public static void main(String[] args) {
Set<Student> students = new HashSet<>();
Student s1 = new Student("马浩楠", 21, '男');
Student s2 = new Student("马浩楠", 21, '男');
Student s3 = new Student("林燕",22,'女');
students.add(s1);
students.add(s2);
students.add(s3);
System.out.println(students);
System.out.println(s1.hashCode());//-1285672988
System.out.println(s2.hashCode());//-1285672988
System.out.println(s3.hashCode());
}
}
概述和特点
TreeSet集合默认的规则
自定义排序规则
两种方式中,返回值规则
【注意】:如果TreeSet集合存储的对象又实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序
public class Student implements Comparable<Student>{
private String name;
private double height;
private int score;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
", score=" + score +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Student(String name, double height, int score) {
this.name = name;
this.height = height;
this.score = score;
}
public Student() {
}
@Override
public int compareTo(Student o) {
//return this.score - o.score;会丢失成绩重复的数据
return this.score - o.score >=0 ? 1:-1;
}
}
public class Test {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(22);
set.add(2);
set.add(26);
set.add(18);
set.add(99);
System.out.println(set);
Set set1 = new TreeSet();
set1.add("Java");
set1.add("java");
set1.add("浩楠");
set1.add("Object");
set1.add("UI");
System.out.println(set1);
System.out.println("------------------");
//方式二(排序):集合自带比较规则
//集合自带的比较规则要比对象内实现的比较器优先级高
Set<Student> students = new TreeSet<>((Student o1,Student o2) -> {
return Double.compare(o1.getHeight(),o2.getHeight());
});
students.add(new Student("张三",170,88));
students.add(new Student("李四",180,90));
students.add(new Student("王五",168,57));
students.add(new Student("程明辉",175,92));
students.add(new Student("李泽",150,92));
System.out.println(students);
}
}
public class Test {
public static void main(String[] args) {
sum();
System.out.println("-----------");
sum(1);
System.out.println("-----------");
sum(new int[]{3,20,50,20,1,0});
}
public static void sum(int...sums){
System.out.println("长度:"+sums.length);
System.out.println(Arrays.toString(sums));
}
}
public class Student implements Comparable<Student>{
private String name;
private double height;
private int score;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
", score=" + score +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Student(String name, double height, int score) {
this.name = name;
this.height = height;
this.score = score;
}
public Student() {
}
@Override
public int compareTo(Student o) {
return this.score - o.score;//List集合允许重复,所以不会像Set集合一样去重数据
//return this.score - o.score >=0 ? 1:-1;
}
}
public class Test {
public static void main(String[] args) {
//1.添加多条数据
ArrayList<String> list = new ArrayList<>();
//list.add("马浩楠");
//list.add("程明辉");
//list.add("李泽");
//list.add("吴赛");
Collections.addAll(list,"马浩楠","程明辉","李泽","吴赛");
System.out.println(list);
//2.shuffel:打乱集合顺序(List集合)
Collections.shuffle(list);
System.out.println(list);
//3.sort:排序
ArrayList<Student> students = new ArrayList<>();
students.add(new Student("张三",170,88));
students.add(new Student("李四",180,90));
students.add(new Student("程明辉",175,92));
students.add(new Student("李泽",150,92));
//Collections.sort(students);
Collections.sort(students,(o1,o2) -> Double.compare(o1.getHeight(),o2.getHeight()) );
System.out.println(students);
}
}
【需求】
在启动游戏房间的时候,应该提前准备好54张牌,完成洗牌、发牌、牌的排序。
Board
public class Board {
private String size;
private String color;
private int index;//比较大小排序的作用
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Board(String size, String color, int index) {
this.size = size;
this.color = color;
this.index = index;
}
@Override
public String toString() {
return size+color;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Board() {
}
}
public class Test {
//1.定义牌集合
public static ArrayList<Board> boards = new ArrayList<>();
//2.定义牌装入集合
static{
String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
String[] colors = {"♥","♦","♣","♠"};
int index = 0;//标记牌的大小方便排序
for (String number : numbers) {
index++;
for (String color : colors) {
boards.add(new Board(number,color,index));
}
}
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < colors.length; j++) {
}
}
boards.add(new Board("","小🃏",index++));
boards.add(new Board("","大🃏",index++));
System.out.println(boards.size());
}
public static void main(String[] args) {
//3.洗牌
Collections.shuffle(boards);
//4.创建玩家牌集合
ArrayList<Board> mahaonan = new ArrayList<>();
ArrayList<Board> chengminghui = new ArrayList<>();
ArrayList<Board> lize = new ArrayList<>();
//5.发牌
for (int i = 0; i < boards.size()-3; i++) {
if(i%3 == 0){
mahaonan.add(boards.get(i));
}else if(i%3 == 1){
chengminghui.add(boards.get(i));
}else if(i%3 == 2){
lize.add(boards.get(i));
}
}
//6.低配(用List中的API方法来截取最后三张)
List<Board> lastThree = Test.boards.subList(Test.boards.size() - 3, Test.boards.size());
//7.给玩家的牌排序
sortBoards(mahaonan);
sortBoards(chengminghui);
sortBoards(lize);
//8.输出玩家的牌
System.out.println("马浩楠的牌:"+mahaonan);
System.out.println("张林燕的牌:"+chengminghui);
System.out.println("燕儿的牌:"+lize);
//9.输出底牌
System.out.println("底牌:"+lastThree);
}
public static void sortBoards(ArrayList<Board> boards){
Collections.sort(boards,(o1,o2) -> o1.getIndex()-o2.getIndex());
}
}
public class Test {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put("鸿星尔克",2);
map.put("Java",1);
map.put("篮球鞋",2);
map.put("Java",100);
map.put(null,null);
System.out.println(map);
}
}
public class Api {
public static void main(String[] args) {
//1.添加元素:无需,不重复,无索引
Map<String,Integer> maps = new HashMap<>();
maps.put("舒肤佳",20);
maps.put("Java",20);
maps.put("卫衣",2);
maps.put("羽绒服",1);
maps.put("Java",30);
System.out.println(maps);
//2.清空集合
//maps.clear();
//System.out.println(maps);
//3.判断集合是否为控,为空返回true
System.out.println(maps.isEmpty());
//4.根据键获取对应值
System.out.println(maps.get("卫衣"));
//5.根据键删除整个元素
System.out.println(maps.remove("羽绒服"));
//6.判断是否包含某个键
System.out.println(maps.containsKey("Java"));
//7.判断是否包含某个值
System.out.println(maps.containsValue(30));
//8.获取全部键的集合
Set<String> keySet = maps.keySet();
//9.获取全部值的集合
Collection<Integer> values = maps.values();
//10.集合的大小
System.out.println(maps.size());
//11.合并其他Map集合
Map<String,Integer> map = new HashMap<>();
map.put("MyBatis",20);
map.put("Spring",2);
Map<String,Integer> map2 = new HashMap<>();
map.put("Spring",4);
map.put("SpringBoot",1);
map.putAll(map2);
System.out.println(map);
}
}
public class Test {
public static void main(String[] args) {
Map<String,Integer> maps = new HashMap<>();
maps.put("舒肤佳",20);
maps.put("Java",20);
maps.put("卫衣",2);
maps.put("羽绒服",1);
maps.put("Java",30);
//1.获取key值的Set集合
Set<String> keySet = maps.keySet();
for (String s : keySet) {
System.out.println(s +"---->"+maps.get(s));
}
}
}
遍历Set集合,然后提取键以及值
涉及到的API
public class Test02 {
public static void main(String[] args) {
Map<String,Integer> maps = new HashMap<>();
maps.put("舒肤佳",20);
maps.put("Java",20);
maps.put("卫衣",2);
maps.put("羽绒服",1);
maps.put("Java",30);
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey()+"---->"+entry.getValue());
}
}
}
public class Test03 {
public static void main(String[] args) {
Map<String,Integer> maps = new HashMap<>();
maps.put("舒肤佳",20);
maps.put("Java",20);
maps.put("卫衣",2);
maps.put("羽绒服",1);
maps.put("Java",30);
// maps.forEach(new BiConsumer<String, Integer>() {
// @Override
// public void accept(String s, Integer integer) {
// System.out.println(s+"---->"+integer);
// }
// });
maps.forEach((s,v) -> {
System.out.println(s+"---->"+v);
});
}
}
public class Test {
public static void main(String[] args) {
//1.吧80个学生的数据拿到
String[] selects = {"A","B","C","D"};
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 80; i++) {
sb.append(selects[random.nextInt(selects.length)]);
}
System.out.println(sb);
//2.定义Map集合,统计最终结果
Map<Character,Integer> maps = new HashMap<>();
//3.遍历80个学生选择的数据
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
if(maps.containsKey(c)){
maps.put(c,maps.get(c)+1);
}else{
maps.put(c,1);
}
}
System.out.println(maps);
}
}
【Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已】
TreeMap和TreeSet底层原理一样
TreeMap集合自定义排序规则两种
public class Test {
public static void main(String[] args) {
//1.记录每个学生的选择
Map<String, List<String>> selects = new HashMap<>();
//2.吧学生选择的数据存入进去
List<String> list = new ArrayList<>();
Collections.addAll(list,"A","C","D");
selects.put("马浩楠",list);
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"A","B","D");
selects.put("程明辉",list1);
List<String> list2 = new ArrayList<>();
Collections.addAll(list2,"A","B","C","D");
selects.put("李泽",list2);
List<String> list3 = new ArrayList<>();
Collections.addAll(list3,"A","C","D");
selects.put("吴赛",list3);
//3.统计每个景点的人数
Map<String,Integer> maps = new HashMap<>();
//4.提取所有人选择的景点信心
Collection<List<String>> values = selects.values();
//values = {[A,C,D],[A,B,D],[A,B,C,D]...}
for (List<String> value : values) {
for (String s : value) {
//判断是否出现过这个景点
if(maps.containsKey(s)){
maps.put(s,maps.get(s)+1);
}else {
maps.put(s,1);
}
}
}
System.out.println(maps);
}
}