zoukankan      html  css  js  c++  java
  • Set;HashSet;LinkedHashSet;Set如何保证元素唯一;Map集合 (Java Day15)

    一,Set

    • 概述:他是单列集合的无序集合,他是所有无序集合的顶层接口。里面的所有功能就是无序集合的共性功能;但是他没有独有的功能,他的功能都是Collection里面的功能,使用的时候就是用Collection接口里面的功能
    • 特点:
    1. 存取数据的顺序不一致【无序】
    2. 没有索引【无索引】
    3. 存放的元素要唯一,不可重复。【元素唯一】
    4. 常见的使用场景:用来进行去重。
    • Set的子类

    • HashSet:

    1. ​ 概述:就是单纯体现无序集合的功能,没有自己特有的功能,体现无序集合的特点。

    代码示例:

    
    import java.util.HashSet;
    import java.util.Iterator;
    public class Demo_HashSet {
    public static void main(String[] args) {
        //创建HashSet集合
        //构造方法
        HashSet<String> set=new HashSet<>();
        set.add("3");
        set.add("6");
        set.add("3");
        set.add("2");
        set.add("4");
        System.out.println(set); //输出的顺序无序,元素不重复唯一,无索引,如果是数字的话是从小到大排序的 [2, 3, 4, 6]
        set.remove("4");
        System.out.println(set); //[2, 3, 6]
        System.out.println(set.size()); //3
    • 遍历

    
    import java.util.HashSet;
    import java.util.Iterator;
    public class Demo_HashSet {
    public static void main(String[] args) {
        //创建HashSet集合
        //构造方法
        HashSet<String> set=new HashSet<>();
        set.add("3");
        set.add("6");
        set.add("3");
        set.add("2");
        set.add("4");
        System.out.println(set); //输出的顺序无序,元素不重复唯一,无索引,如果是数字的话是从小到大排序的 [2, 3, 4, 6]
        set.remove("4");
        System.out.println(set); //[2, 3, 6]
        System.out.println(set.size()); //3  //第一种:数组法遍历
        //集合转数组的时候不管集合是否给定具体的数据类型,都转变成Object类型的数组
        //弊端 遍历之后需要强制转换
        Object[] arr = set.toArray();
       for (int i = 0; i < arr.length; i++) {
            String s = (String) arr[i]; //集合已指定了泛型所以需要强转
            System.out.println(s);
        }
        System.out.println("========");
        
        //第二种:迭代器遍历
        //迭代器对象 [Iterator      ListIterator]
        Iterator<String> it = set.iterator(); //it 为获取的迭代器对象
        while (it.hasNext()) {
            String ss = (String)it .next();// ss 为得到的内容,承载 next()得到的东西
            System.out.println(ss);
        }
        System.out.println("========");
    • 第三种:增强for遍历
    • ​ 概述:理解为是对迭代器遍历的格式得封装改进
    • ​ 格式:for(数据类型 变量名 :容器对象名){拿到元素的处理逻辑}
    • ​ 解释:
    1. ​ for:关键字 代表了循环
    2. ​ 数据类型:容器中存放的数据的数据类型
    3. 变量名:变量 用来存储每次循环遍历得到的内容值
    4. 容器对象名:要遍历的容器
    5. ​ 好处:增强for单纯的进行遍历比较快捷简便
    6. ​ 弊端:遍历的过程中不能够进行相应的增删操作
    7. ​ 增强for的本质是什么?就是迭代器遍历

    代码示例

    
    import java.util.HashSet;
    import java.util.Iterator;
    public class Demo_HashSet {
    public static void main(String[] args) {
        //创建HashSet集合
        //构造方法
        HashSet<String> set=new HashSet<>();
        set.add("3");
        set.add("6");
        set.add("3");
        set.add("2");
        set.add("4");
        System.out.println(set); //输出的顺序无序,元素不重复唯一,无索引,如果是数字的话是从小到大排序的 [2, 3, 4, 6]
        set.remove("4");
        System.out.println(set); //[2, 3, 6]
        System.out.println(set.size()); //3
        
     //增强for遍历
        for(String ss :set) {
            System.out.println(ss);
        }   
    }
    }
    • 总结:
    1. 数组法和迭代器以及增强for可以遍历所有的集合和数组。
    2. 普通for循环遍历能变遍历数组和有序集合【有索引的容器】

    • LinkedHashSet

    • ​ 概述:他是Set集合的一个实现类,同时也是HashSet的子类。他是无序集合中的有序集合,体现无序集合的另外两个特点【在存取顺序上LinkedHashSet是Set集合的叛徒】
    • ​ 特点:
    1. 存取有序【有序】
    2. 没有索引【无索引】
    3. 元素还是唯一不能重复【元素唯一不重复】
    4. ​ 没有自己特有的功能,他的功能和HashSet一样都是Collection的功能
    5. ​ 遍历也是和HashSet一样:数组法、迭代器、foreach

    代码示例

    
    import java.util.Iterator;
    import java.util.LinkedHashSet;
    public class Demo_LinkedHashSet {
    public static void main(String[] args) {
        LinkedHashSet<String>set = new LinkedHashSet<>();
        set.add("春天");
        set.add("夏天");
        set.add("秋天");
        set.add("冬天");
        set.add("春天");
        set.add("夏至");
        set.add("冬至");
        System.out.println(set);//[春天, 夏天, 秋天, 冬天, 夏至, 冬至] 有序排列
        System.out.println("=======");
        
        //第一种:数组遍历
        Object[] arr = set.toArray();
      for (int i = 0; i < arr.length; i++) {
          String ss= (String)arr[i];
          System.out.println(ss);
    }
      System.out.println("==========");
      
      //第二种:迭代器遍历
     Iterator<String>it = set.iterator();
     while (it.hasNext()) {
        String s = (String) it.next();
        System.out.println(s);
    }
     System.out.println("==========");
    
     //第三种:增强for遍历,(foreach)
     for (String name : set) {  // 用name 去接收
        System.out.println(name);
    }
    }
    }
    • 练习
    • 键盘录入一个字符串,输出其中的字符,相同字符只输出一次,要求保证原录入顺序
    • 分析:
    1. 键盘录入一个字符串
    2. 操作的是字符串的字符 【想办法得到字符串的字符】
    3. 挨个把字符存到LinkedHashSet中
    4. 遍历输出或直接输出集合的内容

    代码示例

    
    import java.util.LinkedHashSet;
    import java.util.Scanner;
    public class Test {
        public static void main(String[] args) {
            //1、键盘录入一个字符串
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入一个字符串:");
            String line = sc.nextLine();
            //2、操作的是字符串的字符 【想办法得到字符串的字符】
            char[] cs = line.toCharArray();
            //创建一个LinkedHashSet的对象
            LinkedHashSet<Character> set = new LinkedHashSet<>();
            for (char c : cs) {
                //3、挨个把字符存到LinkedHashSet中
                set.add(c);
            }
            //4、遍历输出或直接输出集合的内容
            System.out.println(set);
        }
    }

    二,Set如何保证元素唯一

    • 重写hashCode
    • 重写equals方法
    • eclipse的操作:
    1. 使用快捷键,直接全部生成:alt + shift + s h
    2. hashCode:是一个native方法,返回的是对象的内存地址,重写这个方法可保证属性值相同的对象的哈希值是一样,不重写返回的哈希值不一样。
    3. hashSet集合 就是根据对象的哈希值来存放数据的
    • 原理:
    1. 调用被添加元素的hashCode(),和HashSet中已有元素的hashCode比较是否相同

    ​          1.1 、如果哈希值不相同,直接存储

    ​          1.2、 如果相同,需要调用equals方法比较是否相同

    • ​ 不相同,直接存储元素
    • ​ 相同,认为是同一元素.不存储

    代码示例:

    //定义一个Person类
    public class Person { private String name; private int age; private String sex; //构造方法 public Person(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } //重写 toString 方法 @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } //重写 hashCode 方法 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sex == null) ? 0 : sex.hashCode()); return result; } //重写 equals 方法 @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; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (sex == null) { if (other.sex != null) return false; } else if (!sex.equals(other.sex)) return false; return true; } }

    //定义一个测试类

    
    import java.util.HashSet;
    public class Demo01 {
    public static void main(String[] args) {
        //创建HashSet
        HashSet<Person> set = new HashSet<>();
       //创建两个人物对象
        Person p = new Person("Jack", 22, "");
        Person p1= new Person("Jack", 22, "");
        System.out.println(" P的hashcode:"+p.hashCode());
        System.out.println(" P1的hashcode:"+p1.hashCode());
        System.out.println(p.equals(p1));//比较属性值
        System.out.println(p == p1); //比较地址值
        //因为没有重写方法所以比较的是地址值
        set.add(p1);
        set.add(p);
        System.out.println(set);
    }
    }

     

    三,Map集合

    • 概述:他是集合体系中的双列集合。每个位置上存放的是一对 [两个] 数据。而且这对数据具有映射关系。
    • 映射关系:通过其一可以找到对应的另一个数据。比如:夫妻关系
    • 键值对数据:就是map集合位置上存放的那对数据。
    1. ​ 键:上面的数据有要求:唯一不可变 [在map集合的所有的键中]
    2. ​ 值:可以有重复的。
    3. 在map集合中的键值对中key [键] 比较重要 [只有通过key可以找对应的值,不能通过值来找到对应的键]
    • 比如:
    • ​ map特点:
    1. map集合是无序的
    2. 他的key值不能出现重复的值【key唯一】
    3. 他的值可以重复的
    4. 通过key可以精确的找到对应的值
    • Map集合的常用方法

    1. put(K k,V v):添加键值对数据到Map集合
    2. remove(K key):根据key删除该key的键值对数据
    3. ​ clear():清空map集合
    4. get(K key):根据Key获取对应的value值
    5. containsKey(K k):判断集合的所有key中是否包含参数k
    6. containsValue(V v):判断集合的所有value值中是否包含参数v

    代码示例:

    
    import java.util.HashMap;
    import java.util.Map;
    public class Demo_Map {
    public static void main(String[] args) {
        //使用Map集合,map是一个接口 必须找他的实现类 使用hashMap
        Map<String, String> map = new HashMap<>();
        map.put("春天", "有花海");
        map.put("夏天", "有大海");
        map.put("秋天", "有果实");
        System.out.println(map);//{夏天=有大海, 秋天=有果实, 春天=有花海} 结果无序
        //为什么现实的不是地址值而是内容值,输出语句直接输出一个对象他是默认去调用toString方法,
        //首先执行自己类中的toString,自己没有执行父类中的toString方法
        map.put("春天", "春暖花开");
        System.out.println(map);//put方法除了添加的功能还有修改键的值的行为,两个功能,添加/修改
        map.remove("夏天");
        System.out.println(map); //key删除了,值也跟着被删除了
        String value=map.get("春天");
        System.out.println(value); //春暖花开,只找现任,不找前任,前任被替换掉了。
        System.out.println(map.containsKey("夏天"));//因为夏天已经被remove掉了 false
        System.out.println(map.containsValue("春暖花开"));//true
        System.out.println(map.keySet()); //[秋天, 春天]
        System.out.println(map.entrySet()); // [秋天=有果实, 春天=春暖花开]
        map.clear();
        System.out.println(map); //{}
        
    }
    }

    练习

    • 键盘录入一个字符串,统计每个字符出现的次数 例如,录入aaaabbccddd!@#@#$@#$%cc66ff 
    • 打印出来:a有4个,b有2个,c有4个,d有3个,!有1个,@有3个,$有2个,%有1个,6有2个,f有2个

    分析:

    代码示例

    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    public class Map_Test {
    public static void main(String[] args) {
        //1,键盘录入字符串
        Scanner sc= new Scanner(System.in);
        System.out.println("录入一个字符串:");
        String line = sc.nextLine();
        
        //2,获取所有字符串中有一个转换字符数组的方法
        char[] cs = line.toCharArray();
    
        //3,得到每一个字符和map集合的可以进行判断是否包含
        //创建map集合
        Map<Character, Integer> map= new HashMap<>();
        for (char c : cs) {
            //C就是每一个字符
            // 进行和map集合的可以进行判断是否包含
            if(map.containsKey(c)){
                //3.1,包含更新字符的个数到集合
                Integer value =map.get(c);
                value++;
                map.put(c, value);
        }else {
            //3.2,不包含添加字符到map集合
            map.put(c, 1);
        }
        }
        //4,输出map集合的内容
        System.out.println(map);
    }
    }

     

  • 相关阅读:
    Windows CE Notification API的使用方法
    探讨如何成为技术团队管理者
    Android应用---基于NDK的samples例程hello-jni学习NDK开发
    在eclipse中配置android ndk的自动编译环境builders
    用javah 导出类的头文件, 常见的错误及正确的使用方法
    Android下NDK开发环境搭建
    Android系统修改硬件设备访问权限
    Android调试工具之ADB
    关于前端小白的一点小建议
    Vue.js简单实践
  • 原文地址:https://www.cnblogs.com/nastu/p/12470534.html
Copyright © 2011-2022 走看看