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

    Java集合框架综述

    1:集合框架(Collection Framework)

    首先要知道 集合代表的是一组对象,和数组差不多 但是数组的长度是固定不变的,而集合是可以变换长度的,比如说:集合就是一根金箍棒,可长可短, 数组就像是一根普通的木棍,长度是固定的,不能变长或者变短。在Java的集合框架中定义了一套规范用来操作集合和具体实现细节,在这里呢也可以把集合想象成一个数据库 ,它有“增删改查”四种操作 ,在本章呢会介绍集合框架的基本类和接口和一些的基本操作方法。

    2:集合框架的两大接口(Collection和Map)

    1.Collection接口

    Collection表示一组对象 ,这些对象也称为collection元素,一个collection允许有重复的值,而另一些则不允许,一些collection是有序的,而有一些是无序的,在Java中没有直接实现collection的 但是它提供了两个子接口 这两个子接口继承了collection接口,那是哪两个接口呢?

    ヾ(✿゚▽゚)ノ  这里介绍两个collection接口的子接口    List   和   Set  

    1.1ArraysLIst类

    ArrayList是List的一个实现类。每一个ArrayList实例都有一个容量,该容量是指用来存储列表的数组大小,它总是等于或者小于列表的大小,随着向ArrayList不断添加元素,其容量也不断的增大。这里ArrayList它跟数组有很多相同点,到底有什么相同点和不同点呢?如下

    那知道ArrayList的概念 怎么创建一个ArrayList集合呢?  定义语法如下:

     1 //创建ArrayList集合 2 List list = new ArraysList(0); 

     在创建ArrayList集合的时候需要导入包:

    //导入包
    import
    java.util.ArrayList; import java.util.List;

    知道了创建ArrayList集合 那怎么向集合里添加元素呢  开始说过java集合框架中定义了一套规范来实现“增伤改查”那怎么实现具体操作呢?下面介绍ArrayList集合的常用方法:

    ArraysLIst 集合的常用方法
    Arrays.asList(); 将数组装换为集合 
    add(Object value); 添加元素
    add(int index,Object value)向指定位置插入元素 
    get(int index);通过下标获取元素 
    set(intindex,Object value);修改指定位置的元素 
    remove(int index); 移除集合中指定位置的元素
    remove(Object o);从集合中移除第一次出现的指定元素(如果存在) 
    removeAll(collection<?>c);从列表中移除制动的collection 中包含的所有元素
    Clear (); 移除集合中所有的元素
    //遍历ArrayList
    foreach(Object item : list){
        //通过get()方法获取元素
    }

    需要注意的是: 1.存储的元素类型都是Object类型

            2.ArrayList集合中是可以添加重复的值,这个跟数组是一样的

                              3. 它的初始容量为10的空列表

    1.2HashSet类

     HashSet是一个哈希集是set的一个重要实现类 它不保证顺序恒久不变,也就是说是无序的,它允许使用NUll元素  但是只能有一个。而且他还不能有重复的值。set中 添加某个对象 无论添加多少次  最终只会保留一个该对象(的引用) 并且 保留的是第一次添加的那一个。既然是无序的所以它没有索引,不能通过索引获取元素。同样跟ArrayList一样它储存的类型也是Object类型。

    那怎么创建一个Hashset呢?  代码如下:

    //创建HashSet(哈希集)
    HashSet hashset= new HashSet();

    在创建HashSet实例时需要导入包:

    import java.util.HashSet;

     

    以下是HashSet类的一些常用方法   如下图:

    add(Object value) 如果此 set中尚未包含指定元素,则添加指定元素 它的返回值是Boolean类型
    
    clear() 移除所有元素
    
    remove(Object o)如果指定元素存在于此 set 中,则将其移除 它的返回值是Boolean类型
    
    size()获取set中的元素的数量  返回值是int
    
    isEmpty()判断该set中是否包含任何元素 返回值是boolean类型
    
    iterator() 返回对此 set 中元素进行迭代的迭代器。

    大家看到Hashset并没有直接获取元素的方法,因为他是无序的 没有索引,这里我们用iterator()方法迭代获取数据,那怎么用呢?代码如下:

     

    import java.util.Iterator;//导包

    itIterator i = hash.iterator(); while(i.hasNext()){ String str = (String)i.next();//需要强转 }

    这里需要注意的是  HashSet里储存是Object类型  需要什么数据类型 就强转成什么数据类型

    上面的是通过Iterator()方法进行迭代  看起来比较麻烦  所以还有一种渐变的方法  通过foreach迭代器进行获取数据 代码如下:

    foreach(Object item in hash){
    
          //获取数据        
    
    }

     上面是Collection接口中的两个子接口 List和Set 下面介绍另一个接口  Map

    2.Map接口

    Map提供了一种映射关系 其中的元素是以键值对(Key-value)的形式存储的 能够实现根据key快速查找Value

    Map中的键值对以Entry类型的对象实例形式存在

    健(key值)不可重复 value值可以
    一个值可以跟很多的key进行映射关系 但一个健(key值)最多只能映射到一个值(value)

     2.1 HashMap类

     HashMap是map的一个重要实现,也是最常用的 基于哈希表实现 它的Entry对象是无序排序的,Key值和value值都可以为null 但是一个HashMap只能有一个kay值为null的映射(key值不可重复)

    介绍了HashMap类的概念 那怎么创建呢?  代码如下:

    //导入包
    import java.util.HashMap;
    //创建Hashmap
    HashMap hash = new HashMap();

    那HashMap类中有什么常用方法呢?如下:

    get(Object key); 指定健获取所映射的值
    Clear();从此映射中移除所有的映射关系
    remove(Object key);从此映射中移除指定键的映射关系(如果存在)
    size();  获取此映射中的键-值映射的关系
    put(K key,V value) 在此映射中关联指定的值与指定键  如果该映射以前包含了一个该键的映射关系  从而达到修改的功能
    entrySet 语法: public Set<Map.Entry<K,V>> enttryset()  返回map中所有的键值对
    KeySet  语法: public Ste<k>keyset()  返回此映射中所包含的键的set视图
    getKey()  获取键 
    getValue() 获取值

    如何向HashMap中添加映射关系呢?如下:

    //创建HashMap
    HashMap hashmap =  new HashMap();
    //通过HashMap类的Put()方法添加映射关系
    hashmap.put(1, "张三");

    这里需要注意的是:1.向HashMap中添加映射关系时  需要指定一个Key(键)指定一个Value(值)从而达到映射关系,

                                     2.同样这里的健(key)和值(value)都是object类型,

    如何获取HashMao中的数据呢?HashMap是键值对可以通过获取键的方法获取数据代码如下:

    //通过HashMap类的gat(object key)获取值
    System.out.println(hashmap.get(1));

    那如何遍历HashMap中的元素呢? 用foreach迭代器实现 代码如下:

    //遍历HashMap的Key值获取数据
    for (Object item:hashmap.keySet()) {
        System.out.println(hashmap.get(item));
                
    }

    其他的方法就不一一测试了  ( ̄▽ ̄)~* 

    那现在有一个问题 比如如下代码:

    List list = new ArrayList();
    list.add("qqyumidi");
    list.add("corn");
    list.add(100);
     for (int i = 0; i < list.size(); i++) {
           String name = (String) list.get(i); //1
           System.out.println("name:" + name);
    }

    定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。

    以上代码中有两个问题:

    A.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

    B.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

    那有什么办法可以使集合能够约束元素类型呢 并达到安逸不报错呢?在Collection和Map中有出现了一个泛型集合。

    3.什么是泛型?

    泛型也可以理解为“参数化类型”,类型的参数化,就是可以把类型像方法的参数那样传递。这一点意义非凡。

    那它有什么作用呢? :泛型使编译器可以在编译期间对类型进行检查以提高类型安全,减少运行时由于对象类型不匹配引发的异常。

    怎么定义个泛型集合呢?把上面的代码修改如下:

    List<String> list = new ArraysList<String>();//定义泛型的语法 
    
    list.add("aaa");
    
    list.add("bbb");
    
    list.add(1111);//1
    
    foreach(String item : list){
    
       System.out.println(item);    
    
    }

    根据上面的代码 得到 定义泛型集合的语法:

    List<E> list  = new ArraysList<E>();
    在List<>尖括号里是要对集合数据类型的约束
    <E>中的E表示类型形参,可以接收具体的类型实参
    上面的代码集合类型是String类型 那么代码“1”我们添加一个int类型的数据 这样编译器是会报错的,因为在定义泛型的时候 限制的是String类型 所以只能添加String类型的数据,
    所以我们总结: 当泛型进行了数据类型约束的时候 不能添加其他的数据类型,否则编译器会报错。
    那么HashSet也可以定义泛型,对元素的数据类型进行约束,那怎么创建HashSet泛型呢?语法如下:
    //创建HashSet泛型
    HashSet<E> hashSet = new HashSet<E>();

    同样是对HashSet中的元素进行数据类型约束 用法如上,具体方法 请往上看HashSet集合的方法。

    需要注意的是:

                     1.泛型集合中 不能添加泛型规定的类型及其子类型以外的对象 否则会报错
                     2.泛型集合中的限定类型 不能使用基本数据类型
                     3. 可以通过使用包装类限定允许存入的基本数据类型

    以上是Collection家族的集合和泛型,那么Map家族有泛型吗?  答案是肯定的  

    HashMap如何定义泛型呢  我们用代码实现一下  代码如下:

    //定义HashMap泛型
    HashMap<K, V> Hashmap = new HashMap<K, V>();

    在HashMap<K,V>

    K代表的是Key(键)的数据类型,

    V代表的值(value)的数据类型,

    也就是说 K键的数据类型必须是规定的数据类型不能是其他的数据类型,值(value)也是一样。

    以上是对泛型的介绍,这里在介绍一下Map中的contains方法:

    contains方法 某个序列是否包含某个对象  如果包含则返回true  如果不包含则返回faslse

    HashMap中:

    ContainsKey(object key); 获取此映射是否包含对于指定建的映射关系
    ContainsValue(object values); 获取此映射是否在此映射中存在的值

    具体怎么使用呢?请看代码:

    Student类

    public class Student {
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
        
    
    }

    test类

    import java.util.HashMap;
    /**
     * ClassName: TestContains 
     * @Description: TODO测试 Map接口的HashMap类的Contains方法
    */
    public class TestContains {
        
        public static void main(String[] args) {
            
            //创建HashMap泛型   键的类型约束是String类型 值的类型约束是学生类(Student)
            HashMap<String, Student> hashmap  = new HashMap<String, Student>();
            //创建一个学生 张三
            Student zs = new Student("A1000", "张三");
            //向泛型中添加元素
            hashmap.put("1",zs);
            //检查是否存在键Key 1
            boolean yesno = hashmap.containsKey("1");
            //输出结果
            System.out.println("Does it contain key1:"+yesno);
            //检查是否包含值 Value “张三”这个学生
            boolean yesno1 = hashmap.containsValue(zs);
            //输出结果
            System.out.println("Does it contain values‘张三’:"+yesno1);
            
        }
    }

    这里我的HashMap中key的约束数据类型是String (这里大家注意下 泛型类型约束不能放基本数据类型 可以放数据类型的类 )value的类型约束是Student类的实例,也是就是说我定义的是学生类  里面只能放一个学生 要是放一个老师就不行。

    言归正传 这里我使用HashMap中的Contains方法来判断泛型中是否包含某个键 或者包含某个对象,它的返回值类型就是Boolean类型,true或false;

    接下来带大家认识两个接口和一个工具类:

    1.Collections(工具类)

    Collections工具类是java集合框架中 用来操作集合对象的工具类,这里我们只介绍一个方法sort();

    在使用之前需要导入工具类的包 代码如下:

    //导入包
    import java.util.Collections;

    sort()方法呢主要是排序 语法如下:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    public class TetsCollectionsSort {
        public static void main(String[] args) {
            
            //创建ArrayList泛型
            List<String> list = new ArrayList<String>();
            //向集合里添加数据
            list.add("aasd");
            list.add("csfgsfd");
            list.add("zasd");
            list.add("gghg");
            //输出排序前
            System.out.println("排序前");
            for (String item : list) {
                System.out.println(item);
            }
            //进行排序
            Collections.sort(list);
            //排序后
            System.out.println("排序后");
            for (String item : list) {
                
                System.out.println(item);
                
            }
        }
    }
    这里发现这些字符串的顺序发生了变化 那么是怎么进行排序的呢?
    答:
    在排序String字符串的时候是比较首字母排序   如果首字母一样则比较第二个字符  如此往下,如果字符串的开头是数字,则比较数字的大小,数字在前,字母在后,
    上面是java集合框架的Collections工具类的sort()方法的介绍,下面介绍一个接口
    2.Comparable接口
    前面介绍了Collections.sort()方法   而要实现序列的排序就要实现comparable接口下面就介绍Comparable接口
    实现该接口表示,这个类的实例可以进行自然排序,
    定义了默认的比较规则
    其实现类需要compareTo()方法
    compareTo
    ()方法返回整数表示大 负数表示小 0表示相等
    一个生活的小案例 在学校里做广播体操时 一般学生的排列都是按照身高去排列,从矮到高排列 因此学生是可以进行比较的,那么我们想两个事物要进行比较,是不是要找到可以比较的方式呢?在我们比较连个事物的时候
    会有一个默认的比较规则,称为自然排序,比如在学生排列的时候这个身高就是可以比较的特性,也是默认的比较规则,那么自然顺序就是身高之间的差异。
    那么如何用代码实现呢? 代码如下:
    Student类
    public class Student{
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
    }
    test类
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    
    /* ClassName: TestContains 
     * @Description: TODO测试comparable接口比较对象
     */
    public class TestContains {
    
        public static void main(String[] args) {
    
            // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student)
            List<Student> list = new ArrayList<Student>();
            // 创建两个学生 张三 李四
            Student zs = new Student("Z1000", "张三");
            Student ls = new Student("V1000", "李四");
            // 向集合中添加元素
            list.add(zs);
            list.add(ls);
            // 排列前
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            // 排列
            Collections.sort(list);//1
            // 排序后
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
    
        }
    }

    这里呢我们的代码1处会报错的  是因为咱们的Student这个类没有实现comparable接口  所以我们要对Student这个类进行改造 修改后的代码如下:

    public class Student  implements Comparable<Student>{
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
    
      //重写comparable的comparato()方法
        @Override
        public int compareTo(Student o) {
            
            return this.id.compareTo(o.id);
        }
        
    
    }

    这里让Student这个类实现Comparable接口  因为接口都是抽象的 所以这里必须重写compareTo()方法  

    这个方法实现  让学生的Id进行一个比较排列 返回整形  那么Test类输出如下:

    排序前
    学号是:Z1000姓名:张三
    学号是:V1000姓名:李四
    排序后
    学号是:V1000姓名:李四
    学号是:Z1000姓名:张三

    这里的排序方法向上面介Collections.sort()方法一样

    3.Comparator接口 ---- 比较工具
    用于定义临时比较规则,而不是默认比较规则
    其实现类需要实现Compare()方法
    强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法
    compare()方法返回整数表示大 负数表示小 0表示相等

    具体实现comparator接口的代码如下:
    StudentComparator类
    import java.util.Comparator;
    
    public class StudentComparator implements Comparator<Student>{
    
      //要实现Comparator接口必须要重写Compare()方法 @Override
    public int compare(Student o1, Student o2) { //按照学生的姓名进行排列 return o1.getName().compareTo(o2.getName()); } }
    Test类修改如下:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    
    /* ClassName: TestContains 
     * @Description: TODO测试comparable接口比较对象和comparator接口
     */
    public class TestContains {
    
        public static void main(String[] args) {
    
            // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student)
            List<Student> list = new ArrayList<Student>();
            // 创建两个学生 张三 李四
            Student zs = new Student("Z1000", "张三");
            Student ls = new Student("V1000", "李四");
            // 向集合中添加元素
            list.add(zs);
            list.add(ls);
            // 排列前
            System.out.println("排序前");
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            // 排列
            Collections.sort(list);
            // 排序后
            System.out.println("排序后");
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            //按照姓名排序如下
            System.out.println("按照姓名排序是:");
            Collections.sort(list,new StudentComparator());
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            
        }
    }

    这里Collections.sort();时需要传递一个集合  和一个实现类的对象,

    本章主要介绍Java集合框架的主要成员有:Collection接口  Map接口 Collections工具类  Comparable接口 Comparator接口

    本章内容到此结束!!!

     




     

  • 相关阅读:
    UVA 1025 A Spy in the Metro DP水题
    ZOJ 3814 Sawtooth Puzzle BFS
    ZOJ 3816 Generalized Palindromic Number
    UVA 10859 Placing Lampposts 树形DP
    UVA 11825 Hackers' Crackdown 状压DP
    POJ 2887 Big String 线段树 离线处理
    POJ 1635 Subway tree systems Hash法判断有根树是否同构
    BZOJ 3110 k大数查询 & 树套树
    sdoi 2009 & 状态压缩
    来自于2016.2.24的flag
  • 原文地址:https://www.cnblogs.com/zkdayup/p/7737529.html
Copyright © 2011-2022 走看看