首页 > 编程语言 >java_day14_HashSet、TreeSet、增强for循环、Map、HashMap、TreeMap、可变参数

java_day14_HashSet、TreeSet、增强for循环、Map、HashMap、TreeMap、可变参数

时间:2024-10-17 20:36:20浏览次数:1  
标签:Map java HashMap int System map1 println public out

一、HashSet

Set:
    HashSet: 底层数据结构是哈希表,查找速度快,且元素唯一


    HashSet中的add方法实际上调用的是HashMap中的put方法
    底层和元素的hashCode方法值有关
    我们发现,底层判断待插入的元素是否已经存在哈希表中的方式是:
    将待插入的元素的哈希值与已经存储在哈希表中元素哈希值进行比较,
    然后再调用待插入的元素的equals方法比较已经存储在哈希表中元素。
    若哈希值一样,且equals结果为true,就表示这两个元素是同一个元素,不做添加

结论:
若想要使用HashSet对元素进行去重,需要元素类型本身重写hashCode方法和equals方法。
public class HashSetDemo1 {
    public static void main(String[] args) {
        //使用HashSet存储字符串元素
        HashSet<String> set1 = new HashSet<>();

        //添加元素
        set1.add("hello");
        set1.add("world");
        set1.add("hello");
        set1.add("java");
        set1.add("hello");
        set1.add("hadoop");

        System.out.println("set1: " + set1);

    }
}

LinkedHashSet

Collection:
    List:
        ArrayList
        Vector
        LinkedList
    Set:
        HashSet:底层数据结构是哈希表,元素唯一,无序
            - LinkedHashSet:底层数据结构是哈希表和双链表。哈希表保证元素唯一,双链表保证元素有序,元素唯一

二、TreeSet

Collection:
    List:
    Set:
        HashSet:
            - LinkedHashSet:
        TreeSet: 底层数据结构是红黑树(自平衡二叉树),具备了可预测的排序
            - 自然排序
            - 比较器排序

TreeSet中的add方法实际上是调用了TreeMap中的put方法


Collection:
    List:
    Set:
        HashSet:
            - LinkedHashSet:
        TreeSet: 底层数据结构是红黑树(自平衡二叉树),具备了可预测的排序
            - 自然排序
            - 比较器排序

TreeSet中的add方法实际上是调用了TreeMap中的put方法

要想使用TreeSet集合存储自定义对象且使用的是无参构造方法创建TreeSet集合对象的话, 需要元素类型实现Comparable<元素类型>接口,实现compareTo方法 compareTo方法根据需求来定制
自定义一个Techer类,该类实现了Comparable接口,并重写其中的CompareTO方法
Techer类部分代码

    @Override
    public int compareTo(Teacher o) {
        //cmp = k.compareTo(t.key);
        // this - 待插入元素
        // o - 要比较的根元素
        //当姓名和年龄一样的时候去重,年龄需要从小到大排序
//        return this.age - o.getAge();
        //显式条件
        int i1 = this.age - o.getAge();
        //隐式条件
        //当年龄一样的时候,姓名不一定一样
        return (i1==0)?this.name.compareTo(o.name):i1;

测试类

public class TreeSetDemo2 {
    public static void main(String[] args) {
        //使用TreeSet存储自定义对象
        TreeSet<Teacher> set1 = new TreeSet<>();
        //需求:当姓名和年龄一样的时候去重,年龄需要从小到大排序
        Teacher t1 = new Teacher("笑哥", 18);
        Teacher t2 = new Teacher("小虎", 15);
        Teacher t3 = new Teacher("凯哥", 17);
        Teacher t4 = new Teacher("笑哥", 18);
        Teacher t5 = new Teacher("杨老板", 18);


        set1.add(t1);
        set1.add(t2);
        set1.add(t3);
        set1.add(t4);
        set1.add(t5);

        for (Teacher teacher : set1) {
            System.out.println(teacher);
        }
    }
}

还有另外一种方法,使用比较器排序,在创建TreeSet集合时传入一个比较器
代码案例

public class TreeSetDemo3 {
    public static void main(String[] args) {
        //使用比较器排序,按照年龄从小到大排序
        //    public TreeSet(Comparator<? super E> comparator) {
        //        this(new TreeMap<>(comparator));
        //    }
        TreeSet<Cat> set1 = new TreeSet<>(new Comparator<Cat>() {
            @Override
            public int compare(Cat o1, Cat o2) {
                // o1是待插入的元素
                // o2是要比较的根元素
                int i1 = o1.getAge() - o2.getAge();
                return (i1 == 0) ? o1.getName().compareTo(o2.getName()) : i1;
            }
        });

        Cat c1 = new Cat("汤姆", 8);
        Cat c2 = new Cat("黑猫警长", 2);
        Cat c3 = new Cat("加菲猫", 4);
        Cat c4 = new Cat("汤姆", 8);
        Cat c5 = new Cat("哆啦A梦", 6);

        set1.add(c1);
        set1.add(c2);
        set1.add(c3);
        set1.add(c4);
        set1.add(c5);

        for (Cat cat : set1) {
            System.out.println(cat);
        }


    }
}

三、增强for循环

增强for循环:是用来替代迭代器的,只能遍历数组以及Collection集合
语句定义格式:
    for(元素的类型 变量名 : 数组|Collection集合){
        直接使用变量名相当于使用元素;
    }

代码案例

public class ForDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();

        list1.add("hello");
        list1.add("world");
        list1.add("java");
        list1.add("hello");
        list1.add("hadoop");

        for (String s : list1) {
            System.out.println(s + "--" + s.length());
        }
        System.out.println("-----------------------");

        int[] arr = {11,22,33,44,55};
        for(int i:arr){
            System.out.println(i);
        }

    }
}

例题:
键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

public class TreeSetTest1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        //创建一个TreeSet集合
        TreeSet<Student2> set1 = new TreeSet<>(new Comparator<Student2>() {
            @Override
            public int compare(Student2 o1, Student2 o2) {
                //显式条件:按照总分从高到低输出到控制台
                int i1 = o2.getSumScore() - o1.getSumScore();
                //隐式条件
                //总分一样,语文成绩不一定一样
                int i2 = (i1 == 0) ? o2.getChinese() - o1.getChinese() : i1;
                //总分一样,语文成绩一样,数学成绩不一定一样
                int i3 = (i2 == 0) ? o2.getMath() - o1.getMath() : i2;
                //各科成绩一样,姓名不一定一样
                return (i3 == 0) ? o2.getName().compareTo(o1.getName()) : i3;
            }
        });

        for(int i=1;i<=5;i++){
            System.out.println("请输入第 "+i+" 个学生的信息");
            System.out.print("请输入姓名: ");
            String name = sc.next();
            System.out.print("请输入该学生的语文成绩: ");
            int chinese = sc.nextInt();
            System.out.print("请输入该学生的数学成绩: ");
            int math = sc.nextInt();
            System.out.print("请输入该学生的英语成绩: ");
            int english = sc.nextInt();
            set1.add(new Student2(name,chinese,math,english));
        }

        System.out.println("学生信息录入完毕!!");
        System.out.println("================= 学生成绩汇总 ===================");
        System.out.println("姓名\t\t语文成绩\t\t数学成绩\t\t英语成绩\t\t总分");
        //遍历集合
        for (Student2 student2 : set1) {
            System.out.println(student2.getName()+"\t\t"+
                    student2.getChinese()+"\t\t"+
                    student2.getMath()+"\t\t"+
                    student2.getEnglish()+"\t\t"+
                    student2.getSumScore());
        }


    }
}

四、Map

Map集合:元素是键值对构成的

Map特点:
    1、在同一个Map集合中,键是唯一的
    2、在同一个Map集合中,值可以发生重复
    3、一对键值,表示Map集合中的一个元素


Map集合中的方法:
    V put(K key,V value)
    V remove(Object key)
    void clear()
    boolean containsKey(Object key)
    boolean containsValue(Object value)
    boolean isEmpty()
    int size()
    V get(Object key)
    Set<K> keySet()
    Collection<V> values()
    Set<Map.Entry<K,V>> entrySet()

代码案例

public class MapDemo1 {
    public static void main(String[] args) {
        HashMap<Integer, String> map1 = new HashMap<>();

        //V put(K key,V value) 向集合中添加一对元素  返回键原本的旧值
//        System.out.println(map1.put(1001, "李刚"));
//        System.out.println("map1: " + map1);
//        System.out.println("----------------------");
//        System.out.println(map1.put(1001, "xiaohu"));
//        System.out.println("map1: " + map1);
        map1.put(1001, "李刚1");
        map1.put(1002, "李刚2");
        map1.put(1003, "李刚3");
        map1.put(1001, "李刚4");
        map1.put(1004, "李刚5");
        System.out.println("map1: " + map1);
        System.out.println("----------------------");
        //V remove(Object key) 根据键移除一个键值对
//        System.out.println(map1.remove(1001));
//        System.out.println("map1: " + map1);
        //void clear()
//        map1.clear();
//        System.out.println("map1: " + map1);

        //boolean containsKey(Object key) 判断键是否存在
//        System.out.println(map1.containsKey(1001));

        //boolean containsValue(Object value) 判断值是否存在
//        System.out.println(map1.containsValue("李刚1"));

        //boolean isEmpty() 判断Map集合中是否有键值对
//        System.out.println(map1.isEmpty());

        //int size() 返回Map集合中键值对的元素个数
//        System.out.println(map1.size());

        //V get(Object key) 根据键获取值
//        System.out.println(map1.get(1001));
//        System.out.println(map1.get(1009)); // null

        //Set<K> keySet() 获取所有的键
//        Set<Integer> keySet = map1.keySet();
//        for (Integer i : keySet) {
//            System.out.println(i);
//        }

        //Collection<V> values() 获取所有的值
//        Collection<String> values = map1.values();
//        for (String value : values) {
//            System.out.println(value);
//        }


    }
}

遍历Map集合

public class MapDemo2 {
    public static void main(String[] args) {
        //Map集合遍历
        HashMap<Integer, String> map1 = new HashMap<>();
        map1.put(1001, "李刚1");
        map1.put(1002, "李刚2");
        map1.put(1003, "李刚3");
        map1.put(1001, "李刚4");
        map1.put(1004, "李刚5");
        System.out.println("map1: " + map1);
        System.out.println("----------------------");

        // 方式1:获取所有的键,遍历键,根据键获取值
//        Set<Integer> keySet = map1.keySet();
//        for (Integer key : keySet) {
//            String value = map1.get(key);
//            System.out.println(key + "-" + value);
//        }

        // 方式2:直接获取所有的键值对,遍历每一个键值对得到每一个键和值
        //Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<Integer, String>> entries = map1.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + ":" + value);
        }
    }
}

1、HashMap

HashMap<Student3,String>

Map的唯一性指的是键的唯一性,HashMap中需要键的类型要重写hashCode()方法和equals方法

二、TreeMap

案例:

"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:
控制台输出"a(5)b(4)c(3)d(2)e(1)"
public class TreeMapTest1 {
    public static void main(String[] args) {
        String s1 = "aababcabcdabcde";

        TreeMap<Character, Integer> map1 = new TreeMap<>();

        //将字符串转字符数组
        char[] chars = s1.toCharArray();

        //遍历字符数组向集合中添加
        for (char c : chars) {
            if (map1.containsKey(c)) {
                map1.put(c, map1.get(c) + 1);
            } else {
                map1.put(c, 1);
            }
        }

        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Character, Integer>> entries = map1.entrySet();
        for (Map.Entry<Character, Integer> entry : entries) {
            Character c = entry.getKey();
            Integer count = entry.getValue();
            sb.append(c).append("(").append(count).append(")");
        }

        String resStr = sb.toString();
        System.out.println("结果为:" + resStr);


    }
}

五、可变参数

代码案例

public class KeBianCanShuDemo {
    public static void main(String[] args) {
        //需求1:求两个int类型的数之和
        int a = 3;
        int b = 4;
        sum(a, b);

        //需求2:求三个int类型的数之和
        int c = 5;
        sum(a, b, c);

        //需求3:求四个int类型的数之和
        int d = 6;
        sum(a, b, c, d);

        int e = 7;
        sum(a,b,c,d,e);

        //需求:传入一个人的姓名和若干门考试成绩,求这个人的总分
        getSumScoreWithName("李刚",98,99,100);
        getSumScoreWithName("钱志强",78,88);
//        getSumScoreWithName2(78,88,"钱志强");

        //可变参数的应用
        //Arrays工具类中有一个方法是将传入的参数封装成一个List集合
        List<Integer> list = Arrays.asList(11, 22, 33, 44, 55); // ArrayList

    }

    //可变参数只能在最后一个参数定义出来
//    public static void getSumScoreWithName2(int... arr,String name) {
//        int sum = 0;
//        for (int i : arr) {
//            sum+=i;
//        }
//        System.out.println(name+"总分为:"+sum);
//    }


    public static void getSumScoreWithName(String name,int... arr) {
        int sum = 0;
        for (int i : arr) {
            sum+=i;
        }
        System.out.println(name+"总分为:"+sum);
    }

    public static void sum(int... arr) {
        int sum = 0;
        for (int i : arr) {
            sum+=i;
        }
        System.out.println(sum);
    }

//    public static void sum(int a, int b) {
//        System.out.println(a + b);
//    }
//
//    public static void sum(int a, int b, int c) {
//        System.out.println(a + b + c);
//    }
//
//    public static void sum(int a, int b, int c, int d) {
//        System.out.println(a + b + c + d);
//    }

}

标签:Map,java,HashMap,int,System,map1,println,public,out
From: https://www.cnblogs.com/w-ll/p/18470979

相关文章

  • JAVA基础知识补漏
    变量类型1.类变量:static2.实例变量:需要new3.局部变量:必须初始化常量final一般用大写表示命名规范所有变量、方法、类名:见名知意类成员变量:首字母小写和驼峰原则:monthSalary局部变量:首字母小写和驼峰原则常量:大写字母和下划线:MAX_VALUE类名:首字母大写和驼峰原则......
  • Java中JDK8-17新特性的学习上
    JDK8-17新特性(第一部分)目录JDK8-17新特性(第一部分)Lambda表达式新的时间/日期API的使用optional类的使用接口增强Lambda表达式Lambda表达式是JDK1.8之后的一种语法,是一个匿名函数,是对匿名函数的简写形式,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行......
  • JavaScript从零学起 —— 数据类型(进阶篇2)
    说明:此文章用作个人学习记录,若有任何问题或建议欢迎大家在评论区讨论文章目录前言一、Boolean(布尔值)1.定义2.实现3.用法示例4.常见问题与解决方法二、Undefined(未定义)1.定义2.实现3.常见问题与解决方法三、Null(空值)1.定义2.实现3.用法示例4.常见问题与......
  • JavaScript网页设计案例
    1.引言在前端开发中,JavaScript无疑是一个非常重要的语言。它不仅可以用于表单验证、动态内容更新,还能实现复杂的交互效果和动画。通过JavaScript,网页变得更加生动和富有互动性。本文将通过一个具体的网页设计案例,详细讲解如何使用JavaScript进行网页开发,包括准备工作、基础理......
  • 归并排序(Java)
    思想:基本思想是使用递归将数组不断分成两半,直到分成的小组都只剩下一个元素为止,随后分别开始排序,将排序好的数组合并在一起。归并排序使用了分治(DivideandConquer)的思想。包括以下三个步骤:划分(Divide):将原问题分解成几个规模较小的相同问题。解决(Conquer):递归求解这些子问......
  • LeetCode:809.情感丰富的文字(双指针 Java)
    目录809.情感丰富的文字题目描述:实现代码与解析:双指针原理思路:809.情感丰富的文字题目描述:        有时候人们会用重复写一些字母来表示额外的感受,比如 "hello"->"heeellooo", "hi"->"hiii"。我们将相邻字母都相同的一串字符定义为相同字母组,例如:"h",......
  • Java基于微信小程序的大学生兼职管理系统,附源码+文档
    博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w+、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • Java多线程编程:深入理解与实践
    java笔记,点击下载在现代软件开发中,多线程编程已成为提高程序性能和响应能力的关键技术之一。Java作为一门高级编程语言,提供了丰富的多线程支持,使得开发者能够轻松地编写并发程序。本文将深入探讨Java多线程的基本概念、实现方式以及最佳实践。多线程的基本概念多线程是指......
  • Topk问题与堆排序(Java数据结构)
    前言:    接触完堆之后,也逐渐对堆了如指掌,最后再来讨论一下两个问题。    有如下场景:    1、全国有几千所大学,我如何能够快速找出排名前10的大学?    2、我如何对这10所大学排好序?    为了用堆解决问题,接下来我们就来一起学习Top......
  • Java数据结构二叉树面试题精华(画图详解)
    前言:    针对二叉树,因为涉及到递归,需要跟多的练习强化递归的思想,其中也包括需要画图理解一些想不通的问题来提升自己!    一下面这些题为例,一起来提升自己的逻辑思维能力!(可能其中一些题已经写过,但是希望能再写一遍有助于提高代码能力)相同的树:      ......