zoukankan      html  css  js  c++  java
  • java集合框架

    2020/4/22 -- Java集合框架和泛型机制

    知识要点:

    • Java集合框架
    • 容器类API
    • Set接口
    • Comparable/comparable 接口
    • List接口
    • Map接口
    • 容器的泛型操作
    • equals和hashcode方法的理解

    Java集合框架概述

    JDK API中专门设计了一组类,这组类的功能就是实现各种方式的数据存储,用于专门存储其它对象的类,称为对象容器类,这组类和接口的设计结构统称为 集合框架(collection Framework)。

    collection接口

    collection接口表示一组对象,这些对象也叫做collection接口的元素,一些collection接口是有序的或者不允许有重复的元素。JDK不提供此接口的任何直接实现,而是提供更具体的子接口如set和List实现。

    Set存放的元素是无序且不包含重复元素;List接口存放的元素是有序的且允许有重复的元素。

    “元素”即对象引用,容器中的元素类型都为Object类型,从容器中取得元素时,必须把它转换成为原来的类型。“重复”是指两个对象通过equals判断相等;“有序”是指元素存入的顺序与取出的顺序相同。

    1. 容器类中单个元素的添加、删除的方法。

      boolean add(Object o);_将对象添加给集合

      boolean remove(Object o)如果集合中有与o匹配的对象,则删除

    2. 容器中元素查询的方法

      int size()返回当前集合中元素的数量

      boolean isEmpty()查找此Collection中是否包含元素

      boolean contains(Object obj)查找此collection中是否包含指定的元素

      boolean contains(Collection c)判断此Collection是否包含指定Collection中的所有元素

      Iterator iterator()返回一个该集合上的迭代器,用来访问该集合中的各个元素。

      boolean containsAll(Collection c)查找该集合中是否包含有集合c中的所有元素

    3. 组操作,作用于元素组或整个集合。

      boolean addAll(Collection c)将指定的集合c中所有元素添加到该集合

      void clear()删除集合中所有元素

      void removeAll(Colletion c)从集合中删除集合c中的所有元素。

      retainAll(Collection c)从当前集合中删除指定集合c中不包含的元素

    4. 转换操作,集合与数组之间的转换

      Object[] toArray()把Collection转换为对象数组

      Object[] toArray(Object[] a)返回一个内含集合所有元素的array。运行期间返回的array和参数a的类型相同,需要转换为正确类型

    可以把集合转换后才能为任何其它数组。但是不能把集合转换成为基本数据类型的数组

    遍历Collection中的元素一般采用Iterator遍历器。以Collection借口定义的子类集合上都有一个与容器类相对应的遍历器。可以通过遍历器遍历出容器中的各个对象元素。

    Iterator借口中定义的方法:

    boolean hasNext()判断游标右边是否有元素

    Object next()返回游标右边的元素并将右边移动到下一个位置

    void remove()删除游标左面的元素

    Set接口实现类

    Set有七个实现类,常用的实现类有三个,HashSet,TreeSet,LinkedHashSet

    根据每哥对象的哈希码值(hashCode())方法获得用固定的算法获得存储索引,把对象存在散列表的想要位置(表元)中:如果计算所得的索引的位置没有元素则直接葌,如果有元素则需要查看是否已经存在该对象,若存在则直接使用该对象,不存在则存入。

    Set接口存取删对象都有很高的效率。对与存放到Set容器中的对象,对应的类一定要重写equals和hashCode(Object obj)方法以实现对象相等原则,如: x.equals(y)为true,那么x.hashCode()的值和y.hashCode()的值相同。

    实现类HashSet

    不保存元素的加入顺序,HashSet类根据元素的哈希码进行存放,所以取出时也可以通过哈希码快速找到。

    	public static void main(String[] args) {
            HashSet hs = new HashSet();
            hs.add("zxx");
            hs.add("zahx");
            Iterator it = hs.iterator();
            while(it.hashNext()) {
                System.out.println(it.next());
            }
        }
    
    public class Student {
        private int age;
        private String name;
        Student(int num, String name) {
            this.name = name;
            this.num = num;
        }
        //显示Student类的信息,必须重写toString()方法
        public String toString() {
            return "age: " + age + " name: "+name;
        }
        // 在java规范中要求,如果用户重写了equals()方法,那么就一定要重写hashCode()方法
        // 两个对象进行equals比较时,如果返回true,呢么它们的hashCode要求返回相等的值
        public int hashCode() {
            return age*name.hashCode();//确定为统一num和相同的name
        }
        public boolean equals(Object o) {
            Student s = (Student) o; // 创建一个新的局部变量
            return age == s.age && name.equals(s.name);
        }
           
    }
    

    实现类LinkedHashSet

    根据哈希码进行存放,同时用链表记录元素的加入顺序。

    Set<Student> linkHashSet = new LinkedHashSet<Student>();
    linkHashSet.add(new Student("11","aaa"));
    linkHashSet.add(null);
    Iterator it = linkHashSet.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
    
    

    通过链表来存储对象,一般插入和删除效率较高,检索效率相等价较低。

    实现类TreeSet

    使用红黑树结构对加入的元素进行排序存放。

    由于TreeSet是自排序的所以在存放自己定义的类的对象时,需要写自己的比较函数实现Comparable接口,通过重写comparaTo()方法实现自定义类的排序。

    public class Student {
        private int age;
        private String name;
        Student(int num, String name) {
            this.name = name;
            this.num = num;
        }
        //显示Student类的信息,必须重写toString()方法
        public String toString() {
            return "age: " + age + " name: "+name;
        }
        // 在java规范中要求,如果用户重写了equals()方法,那么就一定要重写hashCode()方法
        // 两个对象进行equals比较时,如果返回true,呢么它们的hashCode要求返回相等的值
        public int hashCode() {
            return age*name.hashCode();//确定为统一num和相同的name
        }
        public boolean equals(Object o) {
            Student s = (Student) o; // 创建一个新的局部变量
            return age == s.age && name.equals(s.name);
        }
        public int compareTo(Object o) {
            Student s = (Student)o;
            if (s.getAge().compareTo(this.getAge() ) > 0)
                return -1;
            if (s.getAge().compareTo(this.getAge() ) == 0)
                return 0;
            return 1;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
           
    }
    

    推荐使自然排序与equals一致。

    TreeSet自定义比较器,TreeSet有一个构造方法,其允许给定比较器,并根据给定的比较器对元素进行排序。

    public class Student {
        private int age;
        private Integer score;//新增一个成员score
        private String name;
        Student(int age, String name, int score) {
            this.name = name;
            this.age = age;
            this.socre = score;
            
        }
        //显示Student类的信息,必须重写toString()方法
        public String toString() {
            return "age: " + age + " name: "+name;
        }
        // 在java规范中要求,如果用户重写了equals()方法,那么就一定要重写hashCode()方法
        // 两个对象进行equals比较时,如果返回true,呢么它们的hashCode要求返回相等的值
        public int hashCode() {
            return age*name.hashCode();//确定为统一num和相同的name
        }
        public boolean equals(Object o) {
            Student s = (Student) o; // 创建一个新的局部变量
            return age == s.age && name.equals(s.name);
        }
        public int compareTo(Object o) {
            Student s = (Student)o;
            if (s.getAge().compareTo(this.getAge() ) > 0)
                return -1;
            if (s.getAge().compareTo(this.getAge() ) == 0)
                return 0;
            return 1;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }  
           
    }
    
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.LinkedHashSet;
    import java.util.Set;
    import java.util.TreeSet;
    
    //学生年龄比较器
    class StudentAgeComparator implements Comparator<Student> {
        public int compare(Student o1, Student o2) {
            int i = o2.getAge() - o1.getAge();
            return i;
            
        }
    }
    //学生成绩比较器
    class StudentScoreComparator implements Comparator<Student> {
        public int compare(Student o1, Student o2) {
            int i = (int) (o2.getScore() - o1.getScore());
            return i;
        }
    }
    
    public static void main(String[] args) {
        //创建TreeSet对象时选择比较器
        //选择年龄比较器
        Set ts = new TreeSet(new StudentAgeComparator());
    }
    
    
    

    List 接口实现类

    常用的List接口:ArrayList、LinkedList和Vector。

    实现类ArrayList

    ArrayList类支持可随需要正常的动态数组。保存添加顺序

    使用索引取出元素有较高的效率,它可以使用索引来快速定位对象。但元素做删除或插入速度较慢,因为使用了数组,需要移动后面的元素以调整索引顺序。

    Collection c1 = new ArrayList(); //实例化一个具体的子类对象
    c1.add(new Integer(2));//添加
    c1.add("hehe");//添加
    System.out.println("c1:" + c1); //打印结果为:[2, hehe];
    
    Collection c2 = new ArrayList();
    c2.addAll(c1);//将c1的元素添加到c2中
    c2.remove(new Integer(2));//删除
    
    Iterator it = c2.iterator();
    while (it.hasNext()) {
        Object obj = it.next();
        System.out.println("元素:" + obj);
    }
    
    
    //增强for循环来遍历集合中的每一个元素
    for (Iterator it = coll.iterator(); it.hasNext();) {
        Object obj = it.next();
        String str = (String) obj;
        System.out.println(str);
    }
    

    实现类LinkedList

    链接列表数据结构,LinkedList是双向链表实现的容器,所以针对频繁的插入或删除元素使用LinkedList效率较高,适合用于实现Stack和Queue

    • addFirst()在列表头部增加元素
    • addLast()在列表尾部增加元素
    • getFirst()获得第一个元素
    • getLash()获得最后一个元素
    • removeFrist()删除第一个元素
    • removeLast()删除最后一个元素
    public static void main(String[] args) {
        LinkedList linklist = new LinkedList();
        linklist.add("F");
        linklist.add("B");
        linklist.add("D");
        linklist.add("E");
        linklist.add("C");
        
        linklist.addLast("Z");
        linklist.addFirst("A0");
        linklist.add(1,"A1");//在下标为1处添加一个元素
        linklist.remove("F");
        linklist.remove(2);//删除第二个元素
        
        Object val = linklist.get(2);//获得下标为2的元素
        linklist.set(2, (String)var + "changed");
        
        
    }
    

    实现类Vector

    大多数操作与ArrayList类相同,区别之处在于Vector是线程同步的。

    • addElement(Object obj) 添加到尾部
    • insertElement(Object obj, int index)把组件加到所定索引处,此后的内容向后移动
    • setElementAt(Object obj, int index)覆盖原先index内容
    • removeElement(Object obj)把向量中含有本组件的内容移走
    • removeAllElements()清空向量

    java集合与数组的区别:在创建数组时需要明确指明数组的长度,数组一旦创建不能被改变。java集合中不能存放基本数据类型,只能存放对象的引用。

    Map接口

    Map接口用于维护键值对的形式(key/value pairs),描述可不重复的键到值的映射。

    Map底层的键是用Set来存放的,键对应的类必须重写hashCode和equals方法

    Map接口中定义的一些常用方法:

    1. 添加删除操作

      • Object put(Object key, Object value);放入到映像中,该关键字存在则覆盖原有值,返回关键字旧值,如果原先关键字不存在则返回null
      • Object remove(Object key)根据指定的键将键值对从Map中删除
      • void putAll(Map t)将来自特定映像的所有元素添加给该映像
      • void clear()清空Map,键值都可以是null,但是不能把mao作为一个键添或值添加给自己
    2. 元素查询

      • Object get(Object key) 获得与key关联的的值,返回对象,没有返回null
      • boolean containKey(Object key)判断映像中是否存在key
      • boolean containValue(Object value)判断映像中是否存在value
      • int siez()返回当前映像的映射数量
      • boolean isEmpty()判断是否为空
    3. 元视图操作

      • Set keySet() 获取关键字的视图set集。键是唯一的。
      • Collection values()获取值的视图Connection集,值的集合不是唯一的。
      • Set entrySet()

    常用的实现类有:HashMap、TreeMap、Properties

    实现类HashMap

    基于哈希表的Mao接口实现,它是使用频率最高的一个容器,听过所有可选的映射操作,内部对“键”采用三列存放,取值的效率很高,不保证该顺序是恒久不变的。排序是根据哈希算法来排的。

    public static void main(String[] args) {
        HashMap hashmap = new HashMap();
        hash.put("0", "c");
        hash.put("1", "a");
        hash.put("2", "b");
        hash.put("3", "a");
        
        Set set = hashmap.keySet();
        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(hashmap.get(iterator.next()) + ";");//取出存放的值
            
        }
    }
    

    实现类LinkedHashMap

    LinkedHashMap是HashMap的子类,可以按照效率比较高的排列元素,增减。

    LinkedHashMap lhmap = new LinkedHashMap();
    lhmap.put("0", "xmh");
    lhmap.put("1", "xmh");
    lhmap.put("2", "xmh");
    
    Set set = lhmap.keySet();//获取全部键
    Iterator iterator = set.iterator();
    while (ierator.hasNext()) {
        System.out.println(lhmap.get(iterator.next()) + ";");  
    }
    
    

    双重链接列表。此链接列表定义了迭代顺序,即插入顺序,如果映射中重新插入键,则插入顺序不受影响。

    实现类TreeMap

    TreeMap内部红黑树结构实现,对键实行排序存放,所以键必须是可排序的。

    TreeMap treemap = new TreeMap();
    treemap.put("0", "xmh");
    treemap.put("2", "xmh");
    treemap.put("1", "xmh");
    System.out.println(treemap.firstKey());
    
    Set set = treemap.keySet();//获取全部键
    Iterator iterator = set.iterator();
    while (ierator.hasNext()) {
        System.out.println(treemap.get(iterator.next()) + ";");  
    }
    

    实现类Properties

    表示了一个持久性的属性集,可以保存在流中或从流中加载。属性列表都是字符串:字符串的形式。继承与HashTable,即哈希表。

    使用时不建议用put、putAll、get这类存取元素方法,应该用setProperties(String key, Stirng value)、getProperties(String key);

    //创建一个属性文件, 命名为config.properties ,存放在工程的src目录中。
    //文件内容如下:
    #key=value
    name=spirit
    password=abc123
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    public class Properties {
        public static void main(String[] args) {
            //获取文件,并读入到流中
            InputStream is = 	Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties");
            //创建属性集对象
            Properties prop = new Properties();
            try {
                prop.load(is);//从流中加载数据
            } catch (IOException e) {
                e.printStackTrace();
            }
            String name = prop.getProperty("name");
            String pwd  = prop.getProperty("password");
            System.out.println(name);
            System.out.println(pwd);
             
        }
    }
    
  • 相关阅读:
    处理视频流时可能出现的重复帧问题及解决办法
    shell脚本中cd命令无效
    C++教程之初识编程
    若干排序算法的Python实现方法及原理
    C/C++反三角函数使用注意
    ubuntu下安装pip install mysqlclient 报错 command "python setup.py egg_info" failed with error.....解决方案
    使用scrapy框架的monkey出现monkeypatchwarning: monkey-patching ssl after ssl...的解决办法
    机器学习之利用KNN近邻算法预测数据
    python数据分析的工具环境
    python代码实现经典排序算法
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/12755436.html
Copyright © 2011-2022 走看看