集合框架总结(二)

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);

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值