集合

集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。

集合存放的是多个对象的引用,对象本身还是放在堆内存中。

集合可以存放不同类型,不限数量的数据类型。
1、集合框架简介:
   Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储“键对象/值对象”映射
   Collection 接口又有2 种子类型,List、Set,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等
   Map(映射)接口是不同于Collection 接口的另一个重要接口,Map 不是集合,但是它完全整合在集合中
   Map(映射)接口的实现类中,最常用的是HashMap、TreeMap

2、Collection接口
   collection主要方法:

   boolean add(Object o)添加对象到集合
   boolean remove(Object o)删除指定的对象
   int size()返回当前集合中元素的数量
   boolean contains(Object o)查找集合中是否有指定的对象
   boolean isEmpty()判断集合是否为空
   Iterator iterator()返回一个迭代器
   boolean containsAll(Collection c)查找集合中是否有集合c中的元素
   boolean addAll(Collection c)将集合c中所有的元素添加给该集合
   void clear()删除集合中所有元素
   void removeAll(Collection c)从集合中删除c集合中也有的元素
   void retainAll(Collection c)从集合中删除集合c中不包含的元素

   Collection接口的子接口的集合遍历方式:
   //迭代器遍历集合
   List<Student> list = new ArrayList<Student>();
   Iterator<Student> it = list.iterator();
   while(it.hasNext()) {
    System.out.println(it.next());
   }
   //foreach遍历集合
   Set<Student> st = new TreeSet<Student>();
   for (Student student : st) {
    System.out.println(student);
   }
   //for循环遍历集合
   for(int i = 0 ;i<list.size();i++) {  
    int j= (Integer) list.get(i);
    System.out.println(j);  
   }
3、List接口
   List中的元素是有顺序的
   List通常允许重复元素
   List的实现类通常支持null元素
   可以通过索引访问List集合中的元素

   常用方法:
  (1)、添加

   void add(int Index , E element):在list的指定位置插入元素
   void addAll(int index , Collection<? Extends E> e):将指定collection中的所有元素插入到列表中的指定位置

  (2)、删除
   E  remove(int Index):删除指定位置的元素,并返回该元素;

  (3)、修改

   E  set(int index , E element):替换指定位置的元素,并返回被替换的元素

  (4)、获取

   Int  indexOf(Object o):返回指定元素第一次出现的索引,如果该list中不含则返回-1;
   E   get(int Index):返回指定位置的元素;
   
   ArrayList:

   ArrayList基于数组实现,是一个动态的数组队列。但是它和Java中的数组又不一样,它的容量可以自动增长
   由于数据是存入数组中的,所以它的特点也和数组一样,查询很快,但是中间部分的插入和删除很慢
   
   LinkedList:

   LinkedList基于链表实现,在List中间进行插入和删除的代价较低,提供了优化的顺序访问。LinkedList在随机访问方面相对比较慢,但是它的特性集较ArrayList更大

   使用场景:
   ArrayList是由数组实现的,方便查找,返回数组下标对应的值即可,适用于多查找的场景 
   LinkedList由链表实现,插入和删除方便,适用于多次数据替换的场景

4、Set接口
   Set类型容器不能包含重复元素,当加入一个元素到容器中时,需要比较元素的内容是否重复,所以加入Set类型对象容器的对象必须重写equals()方法
   元素可能有顺序,可能没有顺序
   不能基于索引访问Set中的元素
   
   HashSet
   HashSet类是基于哈希算法的Set接口实现的,主要有一下几个特点:
   HashSet中元素没有顺序
   不允许出现重复元素,重复指的是用hashCode()、equals()比较返回true
   允许包含null元素

   如果需要重写equals方法,那么必须重写hashCode方法
   
   TreeSet
   TreeSet集合中的元素有顺序,使用元素的自然顺序对元素进行排序
   TreeSet中不允许使用null元素
   当TreeSet中的元素类型为自定义类型时,必须重写compareTo方法
   public class Student implements Comparable<Student>{
    String  name;
    int age,id;
    public Student (String  name,int age,int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }
    public String  toString () {
        return "name:"+name+"age:"+age+"id:"+id;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public int compareTo(Student s) {
        if(this.id>s.id)
            return 1;
        else if(this.id==s.id)
            return 0;
        else
            return -1;
    }
    
   }

   public class Test03 {

    public static void main(String[] args) {
        Student s1 = new Student ("zhang1",18,16101);
        Student s2 = new Student ("zhang2",28,16102);
        Student s3 = new Student ("zhang3",38,16103);
    
        Set<Student> st = new TreeSet<Student>();
        st.add(s2);st.add(s3);st.add(s1);
        for (Student student : st) {
            System.out.println(student);
        }
    }

   }
   运行:
   name:zhang1age:18id:16101
   name:zhang2age:28id:16102
   name:zhang3age:38id:16103

5、Map(key,value)
   key不能重复,value可以重复

   Map中常见方法:
   1、添加:

   put(K key, V value)  可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null                                          
   putAll(Map<? extends K,? extends V> m)  从指定映射中将所有映射关系复制到此映射中(可选操作)。
   
   2、删除

   remove()    删除关联对象,指定key对象
   clear()     清空集合对象

   3、获取

   get(key)  可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
   size() 返回int类型的集合长度
   4、判断

   boolean isEmpty()   长度为0返回true否则false
   boolean containsKey(Object key)  判断集合中是否包含指定的key
   boolean containsValue(Object value)  判断集合中是否包含指定的value

   Map中所有的key放一起,就组成了一个Set集合,所以Key没有顺序,并不能重复
   Map中的keySet()方法,用于返回Map中所有Key组成的Set对象
  
   把所有的value放一起,就组成了一个可以重复,没有次序的Collection集合
   Map中的Value()方法,用于返回Map中所有Value组成的Collection对象

   HashMap与TreeMap的区别:
   HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()(可以重写hashCode()和equals())
   HashMap :适用于在Map中插入、删除和定位元素。Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
   HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
   HashMap的结果是没有排序的,TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的
   HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map中插入、删除和定位元素,HashMap是最好的选择。TreeMap取出来的是排序后的键值对。但如果要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。


   遍历Map的方式:
    1、将map 集合中所有的键取出存入set集合。
       Set<K> keySet()   返回所有的key对象的Set集合,再通过get方法获取键对应的值。

   2、 values() ,获取所有的值.
       Collection<V> values()不能获取到key对象

   3、 Map.Entry对象
       Set<Map.Entry<k,v>> entrySet()   将map 集合中的键值映射关系打包成一个对象。
       Map.Entry对象通过Map.Entry 对象的getKey,getValue获取其键和值。

   第一种方式:使用keySet
   将Map转成Set集合(keySet()),通过Set的迭代器取出Set集合中的每一个元素(Iterator)就是Map集合中的所有的键,再通过get方法获取键对应的值。

   public class Demo1 {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "aaaa");
        map.put(2, "bbbb");
        map.put(3, "cccc");
        System.out.println(map);

        // 获取方法:
        // 第一种方式: 使用keySet
        // 需要分别获取key和value,没有面向对象的思想
        // Set<K> keySet() 返回所有的key对象的Set集合

        Set<Integer> ks = map.keySet();
        Iterator<Integer> it = ks.iterator();
        while (it.hasNext()) {
            Integer key = it.next();
            String value = map.get(key);
            System.out.println("key=" + key + " value=" + value);
        }
    }
   }

   第二种方式: 通过values()获取所有值,不能获取到key对象
   public static void main(String[] args) {
           Map<Integer, String> map = new HashMap<Integer, String>();
           map.put(1, "aaaa");
           map.put(2, "bbbb");
           map.put(3, "cccc");
           System.out.println(map);

           // 通过values 获取所有值,不能获取到key对象
           // Collection<V> values()
   
           Collection<String> vs = map.values();
           Iterator<String> it = vs.iterator();
           while (it.hasNext()) {
               String value = it.next();
               System.out.println(" value=" + value);
           }
   }
  
   第三种方式: Map.Entry
   public static interface Map.Entry<K,V>   通过Map中的entrySet()方法获取存放Map.Entry<K,V>对象的Set集合。
   Set<Map.Entry<K,V>> entrySet()    面向对象的思想将map集合中的键和值映射关系打包为一个对象,就是Map.Entry,将该对象存入Set集合,Map.Entry是一个对象,那么该对象具备的getKey,getValue获得键和值。
   public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "aaaa");
        map.put(2, "bbbb");
        map.put(3, "cccc");
        System.out.println(map);

        // Set<Map.Entry<K,V>> entrySet()
        // 返回的Map.Entry对象的Set集合 Map.Entry包含了key和value对象
        Set<Map.Entry<Integer, String>> es = map.entrySet();

        Iterator<Map.Entry<Integer, String>> it = es.iterator();

        while (it.hasNext()) {
            
            // 返回的是封装了key和value对象的Map.Entry对象
            Map.Entry<Integer, String> en = it.next();

            // 获取Map.Entry对象中封装的key和value对象
            Integer key = en.getKey();
            String value = en.getValue();

            System.out.println("key=" + key + " value=" + value);
        }
    }

原文地址:https://www.cnblogs.com/snzd9958/p/9525946.html