zoukankan      html  css  js  c++  java
  • Java:Collection集合类

    特点:只能用于存储对象,集合长度时可变的,集合可以存储不同类型的对象。

    数组和集合类同时容器,不同的是:

    1、数组虽然也可以存储对象,但是长度是固定的;集合长度时可变的。

    2、数组中可以存储基本数据类型,集合只能存储对象。

    集合关系:

    Collection:它是抽象类,它的子类如下:两个直接子类,子类下还有一些子类

    |-------list

             |--------ArrayList    数组集合

             |--------LinkedList   链表集合

             |--------Vector        数组集合

    |-------set     

             |-------HashSet        哈希表集合

             |-------TreeSet        二叉树集合

    3、遍历集合中的元素主要用迭代器Iterator

    集合有很多的方法,可以查看API,这里做简单的介绍:

    1、add()方法的参数类型是Object。以便于接受任意类型的对象。

    2、集合中存储的都是对象的引用(地址)

    注意:建立一个集合时,可以用的方法-----

    步骤:一、使用Collection接口的子类创建一个集合对象   例如:ArrayList al = new ArrayList();

             二、对集合进行操作:al.add(Object obj) 添加元素(对象)

                         al.contains(Object obj) 判断集合中是否含有此元素(对象)  

                       al.remove(Object obj) 删除集合中的指定元素(对象)  

                                           al.size() 获取集合的长度,也即元素(对象)个数

                                           al.isEmpty()判断集合是否为空

                                           al.clear() 清空集合

    //例子1:

    import java.util.*;
    class CollectionTest
    {
        public static void sop(Object obj)
        {
            System.out.println(obj);
        }
        public static void main(String[] args)
        {
            //创建一个集合容器。使用Collection接口的子类。ArrayList
            ArrayList al = new ArrayList();
            
            //1、添加元素
            al.add("java01");//add(Object obj),添加的是字符串对象,采用了多态的形式
            al.add("java02");
            al.add("java03");
            al.add("java04");
          
          
            //2、获取元素个数,集合长度
            sop("size="+al.size());
            
            
            //3.判断元素是否存在
            sop("boolean="+al.contains("java02"));
            //  判断集合是否为空
            sop("boolean="+al.isEmpty());
            
            
            //打印原集合
            sop("al="+al);
            
            
            //4、删除元素
            al.remove("java04");
            
            //打印删除后的集合
            sop("al="+al);
            
            
            //5、清空集合
            al.clear();
            
            //打印清空后的集合
            sop("al="+al);
            
    
        }
    }

    注意:建立两个个集合时,可以用的方法如下---

    步骤:一、使用Collection接口的子类创建两个集合对象   

                     例如:ArrayList al = new ArrayList();

      ArrayList at = new ArrayList();

             二、对集合进行操作:

    //例子2: 

    import java.util.*;
    class CollectionTest1
    {
        public static void sop(Object obj)
        {
            System.out.println(obj);
        }
        public static void main(String[] args)
        {
            //创建两个集合容器。使用Collection接口的子类。ArrayList
            ArrayList al = new ArrayList();
            ArrayList at = new ArrayList();
            
            //1、添加元素
            al.add("java01");//add(Object obj),添加的是字符串对象,采用了多态的形式
            al.add("java02");
            al.add("java03");
            al.add("java04");
            
            at.add("java01");//add(Object obj),因为添加的是对象,所以必须是obj,采用了多态的形式
            at.add("java02");
            at.add("java05");
            at.add("java06");
            
            //2、判断两个集合是否有交集,al中只保留与at中相同的元素
            sop("boolean="+al.retainAll(at));
            sop("al="+al);
            sop("at="+at);
            
            //3、删除交集,删除al中含有at中的元素
            al.removeAll(at);
            sop("al="+al);
            sop("at="+at);
            
            //4、添加集合,也即将at集合的所有元素添加到al集合
            al.addAll(at);
            sop("al="+al);
            sop("at="+at);
            
            //5、判断一个集合是否包含另一个集合中的所有元素,也即判断al中是否包含at中的所有元素
            sop("boolean="+al.containsAll(at));
        }
    }

    获取迭代器(相当与遍历),用于获取集合中的元素 Iterator iterator()

    jdk1.5新加内容往集合存放数据检查类型比List、Iterator等

    Iterator<E> it = al.iterator()中的 E 表示Object,这是一个泛型迭代器。

    举例

    ArrayList<String> stringList = new ArrayList<String>();

    stringList能接受String类型参数,编译JVM会做类型检查

    接口 Iterator<E>中的方法:

     1、boolean hasNext() : 如果仍有元素可以迭代,则返回 true

     2、E(Object) next() : 返回迭代的下一个元素。

     3、void remove() : 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

     什么是迭代器:其实就是集合的取出元素的方式

     就是取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素。

     那么取出方式就被定义成了内部类。

     而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容:判断和取出。

     那么可以将这些共性抽取。

     那么这些内部类都符合一个规则。该规则就是Iterator接口。

     如何获取集合取出对象呢?

     通过一个对外提供的方法 iterator()

    //例子3: 

    import java.util.*;
    class CollectionTest2
    {
        public static void sop(Object obj)
        {
            System.out.println(obj);
        }
        public static void main(String[] args)
        {
            //创建一个集合容器。使用Collection接口的子类。ArrayList
            //ArrayList <E>al = new ArrayList();==========>ArrayList al = new ArrayList()
            ArrayList <String>al = new ArrayList();
            
            //添加元素
            al.add("java01");//add(Object obj),添加的是字符串对象,采用了多态的形式
            al.add("java02");
            al.add("java03");
            al.add("java04");
            
            /*
            //获取集合中的元素(方式一:缺点是while循环结束后,it对象仍然存在于内存中,既没有了意义,也浪费空间)
            Iterator it = al.iterator();  //返回一个Iterator接口引用型变量指向的子类对象,它不是通过new创建的,而是通过方法获取的
            while(it.hasNext())
            {
                    sop(it.next());//取出元素
                    it.remove();//删除元素        
            }
                    sop(al);//用迭代器清空集合后,集合元素为空
                
    
                
            //获取集合中的元素(方式二:优点是循环结束后,it对象就不存在了,节约内存空间)
            for(Iterator it = al.iterator();it.hasNext();)
            {
                sop(it.next());//取出元素
            }
            */
            
            //获取集合中的元素(方式三:优点是简化了代码的书写)
            for(String element:al)
            {
                sop(element);//取出元素
            }
        }        
    }

    Set接口的集合功能和Collection根接口的功能完全一样。它的主要两个实现子类是HashSet、TreeSet

    set集合中的元素:无序的,即存入和取出的顺序不一定一致。而且元素是唯一的,不可重复,,,,,

    //例子4

    import java.util.*;
    class HashSetDemo
    {
        public static void sop(Object obj)
        {
            System.out.println(obj);
        }
        public static void main(String[] args)
        {
            // 创建集合容器
            HashSet hs = new HashSet();
            
            // 添加元素
            sop(hs.add("java01"));//true
            sop(hs.add("java01"));//false
            hs.add("java02");
            hs.add("java03");
            hs.add("java03");
            hs.add("java04");
            
            
            Iterator it = hs.iterator();
            while(it.hasNext())
            {
                sop(it.next());
            }
        }
    }

    那么hashset是如何保证元素的唯一性呢?

      是通过元素的两个方法,hashcode和equals来完成,如果元素的hashcode值相同,才会判断equals是否为true。如果元素的hashcode

      值不同,不会调用equls方法。

      注意:对于判断元素是否存在,以及删除等操作,依赖的的方法是hashCode()和equals()。

      结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode

            返回相同的整数,而且equals()返回值为True。 

            如果偷懒,没有设定equals(),就会造成返回hashCode虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。 

    例子: 

    public int hashCode(){ 

    return name.hashcode()+age; 

    这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。

    //例子5:

    import java.util.*;
    class Person
    {
        private String name;
        private int age;
        Person(String name,int age)
        {
            this.name = name;
            this.age = age;
        }
        public int hashCode()
        {
            System.out.println(this.getname()+".....hashCode");
            return name.hashCode()+age;
        }
        public  boolean equals(Object obj)
        {
            if(!(obj instanceof Person))
                return false;
            Person p = (Person)obj;
            System.out.println(this.name+"....equals...."+p.name);
            
            return this.name.equals (p.name) && this.age == p.age;        
        }
        public String getname()
        {
            return name;
        }
        public int getage()
        {
            return age;
        }
    }
    class HashSetDemo1
    {
        public static void main(String[] args)
        {
            HashSet hs = new HashSet();
            
            hs.add(new Person("a1",10));
            hs.add(new Person("a2",11));
            hs.add(new Person("a2",11));
            hs.add(new Person("a3",12));
            
            sop("a1:"+hs.contains(new Person("a1",10)));//先用hashcode()输出a1的哈希值,然后和集合中的a1进行equals比较
            hs.remove(new Person("a3",12));//先用hashcode()输出a3的哈希值,然后和集合中的a3进行equals比较
            
            Iterator it = hs.iterator();
            while(it.hasNext())
            {
                Person p = (Person)it.next();
                sop(p.getname()+"::"+p.getage());
            }
        }
        public static void sop(Object obj)
        {
            System.out.println(obj);
        }
    }

     TreeSet集合:特点是可以对集合中的元素进行自然排序,所以所要比较的对象必须具有比较性。

    需求:(自定义存储对象)向集合中存储学生类对象,然后按照年龄大小进行排序后输出。

    定义比较性的方法:定义一个类,实现Compareble接口, 并重写compareTo方法。

    记住:排序时,如果主要条件相同时,一定要判断次要条件.......

    TreeSet排序的第一种方式:让元素具备比较性。元素需要实现compareble接口,覆盖compareTo方法,这种方式也称为自然顺序或默认顺序....

    //例子6:

    class Student implements Comparable //实现Comparable接口,强制让学生对象具有比较性。
    {
        private int age;
        private String name;
        Student(String name,int age)
        {
            this.name = name;
            this.age = age;
        }
        public int compareTo(Object obj)  //覆盖接口的方法,程序运行时,底层自动调用,按年龄大小排序后输出
        {
            /*
             return 1;   //直接怎么存入的就怎么输出来
            */    
            
            /*
             return -1;   //直接怎么存入的就倒着输出来)
            */
            if(!(obj instanceof Student))
                throw new RuntimeException("不是学生对象");
            Student s = (Student)obj; //(多态性)强转
                TreeSetDemo.sop(this.name+"...compareTo...."+s.name);
                if(this.age>s.age)
                    return 1;
                if(this.age==s.age)  //判断是否是同一个对象
                {
                    return this.name.compareTo(s.name);
                }
                return -1;
        }
        public String getname()
        {
            return name;
        }
        public int getage()
        {
            return age;
        }
    } 
    class TreeSetDemo
    {
      public static void sop(Object obj)
      {
          System.out.println(obj);
      }  
      public static void main(String[] args)
      {
          TreeSet ts = new TreeSet();
          
          ts.add(new Student("lisi01",19));
          ts.add(new Student("lisi007",15));
          ts.add(new Student("lisi03",30));
          ts.add(new Student("lisi02",24));
          ts.add(new Student("lisi02",23));//同名字不同年龄
          ts.add(new Student("lisi04",23));//不同名字同年龄
    
            
    /*      for(Object element: ts)
          {
             sop(element); 
          }    
    */      
          Iterator it = ts.iterator();
          while(it.hasNext())
          {
              Student stu = (Student)it.next();
              sop(stu.getname()+"...."+stu.getage());
          }
      }  
    }

    TreeSet排序的第二种方式:当元素自身不具备比较性或具备的比较性不是所需要的,这时,就需要让集合具备比较性。在集合初始化时,就有了比较方式。

      定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造参数里。

      记住:排序时,如果主要条件相同时,一定要判断次要条件.......

      当两种排序都存在时,以比较器为主。

      定义比较器的方法:定义一个类,实现comparator接口,覆盖compare方法,返回1、0或-1.....

    //例子7:

    class Student //implements Comparable //实现Comparable接口,强制让学生对象具有比较性。
    {
        private int age;
        private String name;
        Student(String name,int age)
        {
            this.name = name;
            this.age = age;
        }
        
        /*
        public int compareTo(Object obj)  //覆盖接口的方法,程序运行时,底层自动调用,按年龄大小排序后输出
        {
            
             //return 1;   //直接怎么存入的就怎么输出来
                
            
            
            // return -1;   //直接怎么存入的就倒着输出来)
            
            if(!(obj instanceof Student))
                throw new RuntimeException("不是学生对象");
            Student s = (Student)obj; //(多态性)强转
                TreeSetDemo.sop(this.name+"...compareTo...."+s.name);
                if(this.age>s.age)
                    return 1;
                if(this.age==s.age)  //判断是否是同一个对象
                {
                    return this.name.compareTo(s.name);
                }
                return -1;
        }
        */
        
        public String getname()
        {
            return name;
        }
        public int getage()
        {
            return age;
        }
    } 
    class TreeSetDemo2
    {    
        public static void sop(Object obj)
            {
              System.out.println(obj);
            }  
        public static void main(String[] args)
        {
        
            TreeSet ts = new TreeSet(new Mycompare());//在TreeSet构造函数里传递一个比较器
              
            ts.add(new Student("lisi01",19));
            ts.add(new Student("lisi007",15));
            ts.add(new Student("lisi007",16));//同名不同年龄
            ts.add(new Student("lisi03",30));
            ts.add(new Student("lisi03",30));//同名同年龄
            ts.add(new Student("lisi02",24));
            ts.add(new Student("lisi04",23));
            
    /*      for(Object element: ts)
          {
             sop(element); 
          }    
    */      
          Iterator it = ts.iterator();
          while(it.hasNext())
          {
              Student stu = (Student)it.next();
              sop(stu.getname()+"...."+stu.getage());
          }
        }
    }
    class Mycompare implements Comparator  //实现集合比较器接口,强行对某个对象 collection 进行整体排序的比较函数
    {
        public int compare(Object o1,Object o2)
        {
            Student s1 = (Student)o1;
            Student s2 = (Student)o2;
            int num = s1.getname().compareTo(s2.getname());
            if(num==0)
            {  
                  return s1.getage()-s2.getage();
        
               // return new Integer(s1.getage().compareTo(s2.getage()));
                
              /*
                if(s1.getage()>s2.getage())
                    return 1;
                if(s1.getage()==s2.getage())
                    return 0;
                return -1;
                */
            }
            return num;
        }
    }        

     Map<K,V>集合接口 

    特点:类似于Collection的顶层集合,该集合存储键值对,一对一对往里存储,而且要保证键的唯一性。

    方法:

    1、添加:

             V put(K key, V value)  

             void putAll(Map<? extends K,? extends V> m) 

    2、删除:

             void clear()

             V remove(Object key)    

    3、判断:

             boolean containsKey(Object key) 

             boolean containsValue(Object value) 

             boolean isEmpty()  

    4、获取:

             V get(Object key)

             int size()

             Collection<V> values()  

             Set<Map.Entry<K,V>> entrySet()  

             Set<K> keySet() 

      Map:

             |--Hashtable:底层是哈希表结构,不可以存入null键和null值,该集合是同步的,JDK1.0。但是效率低...

             |--HashMap  :底层是哈希表结构,可以存入null键和null值,该集合是不同步的,JDK1.2。但是效率高...

             |--TreeMap  :底层是二叉树结构,线程是不同步的,可以用于对Map集合的键进行排序....

     Map和Set很像,其实Set集合底层就是使用了Map集合。

     //例子8:

    import java.util.*; 
    class MapDemo
    {
        public static<T> void sop(T t)
        {
            System.out.println(t);
        }
        public static void main(String[] args)
        {
            Map<String,String> map = new HashMap<String,String>();
            //添加,如果出现添加时,相同的键,那么后添加的值会替换原有的键对应的值。而且,put方法会返回被覆盖的那个键值
            sop(map.put("01","zhang"));//null
            sop(map.put("01","zhangsan1"));//zhang 
            map.put("02","zhangsan2");
            map.put("03","zhangsan3");
            sop(map);//原键值对 {01=zhangsan1,02=zhangsan2,03=zhangsan3}
            
            //判断
            sop("contains:"+map.containsKey("02"));  //true
            sop("contains:"+map.containsKey("022"));  //false
            
            //删除
            sop("remove:"+map.remove("022"));  //null,此键不存在
            sop("remove:"+map.remove("02"));  //zhangsan2,显示的是删除的键值
            sop(map);//删除后的键值对
            
            //获取
            sop("get:"+map.get("03"));//zhangsan3
            sop("get:"+map.get("033"));//null,此键不存在
            
            
            //获取map集合中所有的值
            Collection<String> co = map.values();
            sop("values:"+co);
            
            
            //HashMap中允许null键的键值存在
            map.put(null,"haha");
            sop("get:"+map.get(null));
            sop(map);
            
            
            //HashMap中可以通过get方法来判断键是否存在,通过返回null来判断
            map.put("haha",null);
            sop("get:"+map.get(null));
            sop(map);
        }
    } 

    map集合的两种取出方式:keyset()、entryset()

    map集合的取出原理:将map集合转成set集合,再通过迭代器取出。

    1、Set<K> keySet()  :将map中所有的键存入set集合中,因为set具备迭代器,可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。

     //例子9:

    import java.util.*;
    class MapDemo2
    {
        public static<T> void sop(T t)
        {
            System.out.println(t);
        }
        public static void main(String[] args)
        {
            Map<String,String> map = new HashMap<String,String>();
            
            //添加
            map.put("03","zhangsan3");
            map.put("02","zhangsan2");
            map.put("01","zhangsan1");
            map.put("04","zhangsan4");
    
            
            //(一)用Set<K> keySet()方式获取集合
            
            Set<String> keyset = map.keySet();//先获取map集合的所有键的set集合,通过keyset()方法.
            
            Iterator<String> it = keyset.iterator();//有了set集合,就可以用其迭代器获取
            while(it.hasNext())
            {
                String key = it.next();//获取所有的键
                sop("key:"+key);
                String value = map.get(key);//获取所有的键对应的值
                sop("value:"+value);
            }
        }
    }

    2、Set<Map.Entry<K,V>> entrySet():将Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry<K,V>

    例子10:

    import java.util.*;
    class MapDemo3
    {
        public static<T> void sop(T t)
        {
            System.out.println(t);
        }
        public static void main(String[] args)
        {
            Map<String,String> map = new HashMap<String,String>();
            
            //添加
            map.put("03","zhangsan3");
            map.put("02","zhangsan2");
            map.put("01","zhangsan1");
            map.put("04","zhangsan4");
    
            
            //(二)用Set<Map.Entry<K,V>> entrySet()方式获取集合
            
            //将Map集合中的映射关系取出,存入到Set集合中。
              Set<Map.Entry<String,String>> entryset = map.entrySet();
            //有了Set集合后,就可以用迭代器取出映射关系了。
              Iterator<Map.Entry<String,String>> it = entryset.iterator();
              
        /*      while(it.hasNext())
              {
                  Map.Entry<String,String> m = it.next(); //获取所有的映射关系
                  sop("Map.Entry:"+m);//直接输出所有的映射关系
              }  
        */      
              while(it.hasNext())
              {            
                  Map.Entry<String,String> m = it.next(); //获取所有的映射关系
                  String key = m.getKey(); //获取所有的键
                  String value = m.getValue();//获取所有的键对应的值
                  sop("key:"+key+" "+"value:"+value);//间接输出所有的键和键值
              }
        }
    }
  • 相关阅读:
    Centos搭建SVN服务器
    JavaScript 对象 之创建对象 学习笔记
    ThinkPHP 学习记录
    Git 版本控制 在 WIN 下的一些使用方法
    关于 CSS 的重用性
    双飞翼布局和圣杯布局
    cocos2dx3.8 ios打包脚本编写
    如何做dragonbones的lua绑定(xcode)
    【转】如何做dragonbones的lua绑定(Android)
    【转】如何做dragonbones的lua绑定(VisualStudio)
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4915823.html
Copyright © 2011-2022 走看看