Java集合详解

Java集合详解


所有集合所在的包:java.util
集合是java中提供的一种容器,可以用来存储多个数据。
集合按照其存储结构可以分为两大类,分别是单列集合 java.util.Collection 和双列集合 java.util.Map


扩展

集合的初始化大小与自动扩容机制以(ArrayList为例)

  • 初始化大小:默认的构造器,将会以默认的大小来初始化内部的数组:public ArrayList();如果刚刚创建的arraylist集合的话 其默认的大小是为0;(注意:在jdk1.6中ArrayList中创建出来的集合默认大小是10)
  • 自动扩容机制:如果当前集合没有添加任何值的情况下,其大小还是为0,当添加第一个数据到集合中时,java会重新初始化集合大小为10.当集合大小刚刚到10的时候,集合不会自动扩容,当添加第11个数据的时候,Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,继续扩容变为15 * 1.5 =22个;

集合和数组既然都是容器,它们有啥区别呢?

  • 数组的长度是固定的。集合的长度是可变的。
  • 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

集合接口


  • Interface Collection<泛型> //继承了Iterable<泛型>接口
  • Interface List<泛型> //继承了Collection<泛型>接口
  • Interface Set<泛型> //继承了Collection<泛型>接口
  • Interface Map<键,值>

接下来依次分析每个集合接口


Interface Collection<泛型>


Collection特点(并没说其子类):
1. 允许元素重复
2. 有先后顺序
3. 有索引值
Collection的分类情况:
Collection的分类情况


Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。

  • public boolean add(E e) : 把给定的对象添加到当前集合中 。
  • public void clear() :清空集合中所有的元素。
  • public boolean remove(E e) : 把给定的对象在当前集合中删除。
  • public boolean contains(E e) : 判断当前集合中是否包含给定的对象。
  • public boolean isEmpty() : 判断当前集合是否为空。
  • public int size() : 返回集合中元素的个数。
  • public Object[] toArray() : 把集合中的元素,存储到数组中。
    如需了解更多,自行翻看JDK字典
    下面简单运用一下:
public class Demo1Collection {
    public static void main(String[] args) {
     // 使用多态形式    
     Collection<String> coll = new ArrayList<String>();    
     // 使用方法    
     // boolean  add(String s)  添加功能  
     coll.add("小李广");    
     coll.add("扫地僧");    
     coll.add("石破天");    
     System.out.println(coll); // [小李广, 扫地僧, 石破天]   
     // boolean contains(E e) 判断o是否在集合中存在    
     System.out.println("判断扫地僧是否在集中"+coll.contains("扫地僧")); // true   
     //boolean remove(E e) 删除在集合中的o元素    
     System.out.println("删除石破天:"+coll.remove("石破天")); // true    
     System.out.println(coll); // [小李广, 扫地僧]   
     // size() 集合中有几个元素    
     System.out.println("集合中有"+coll.size()+"个元素"); // 2       
     // Object[] toArray()转换成一个Object数组        
     Object[] objects = coll.toArray();    
     // 遍历数组    
     for (int i = 0; i < objects.length; i++) {    
         System.out.print(objects[i]+" "); // 小李广 扫地僧          
        }        
     // void  clear() 清空集合        
     coll.clear();        
     System.out.println("集合中内容为:"+coll); // []      
     // boolean  isEmpty()  判断是否为空        
     System.out.println(coll.isEmpty()); // true            
    }    
}

Interface List<泛型>


List的特点


  1. 它是一个元素存取有序的集合 ->有序指的是先后顺序,而非大小顺序
  2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素
  3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

  • public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
  • public E get(int index) :返回集合中指定位置的元素。
  • public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
    演示代码如下:
  public class ListDemo {
    public static void main(String[] args) {
    // 创建List集合对象        
     List<String> list = new ArrayList<String>();         
     // 往尾部添加指定元素    
     list.add("图图");    
     list.add("小美");    
     list.add("不高兴");    

     System.out.println(list); // [图图, 小美, 不高兴]    
     // add(int index,String s) 往指定位置添加    
     list.add(1,"没头脑");    

     System.out.println(list); // [图图, 没头脑, 小美, 不高兴]    
     // String remove(int index) 删除指定位置元素  返回被删除元素    
     // 删除索引位置为2的元素   它会将返回的值返回         
     System.out.println(list.remove(2)); // 小美   

     System.out.println(list); // [图图, 没头脑, 不高兴]   

     // String set(int index,String s)   在指定位置 进行 元素替代     
     // 修改指定位置元素    
     list.set(0, "三毛");    
     System.out.println(list); // [三毛, 没头脑, 不高兴]     
     // String get(int index)  获取指定位置元素      
     // 跟size() 方法一起用  来 遍历的     
     for(int i = 0;i<list.size();i++){    
     System.out.print(list.get(i)+" "); // 三毛 没头脑 不高兴        
   }  
     System.out.println(); // 换行 
     //还可以使用增强for    
     for (String string : list) {    
     System.out.print(string+" "); //没头脑 不高兴           
    }
  }
}

List的子类


ArrayList
  • java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以 ArrayList 是最常用的集合。
  • ArrayList 中可不断添加元素,其大小也自动增长。(参考上方扩展的自动扩容机制)
  • 方法请看其父类LIst,Collection
LinkedList
  1. java.util.LinkedList 集合数据存储的结构是链表结构,而且还是双向链表,方便元素添加、删除的集合,但查找慢。
  2. LinkedList是List的子类,List中的方法LinkedList都是可以使用,LinkedList还有特有方法。
    • public void addFirst(E e) :将指定元素插入此列表的开头。
    • public void addLast(E e) :将指定元素添加到此列表的结尾。
    • public E getFirst() :返回此列表的第一个元素。
    • public E getLast() :返回此列表的最后一个元素。
    • public E removeFirst() :移除并返回此列表的第一个元素。
    • public E removeLast() :移除并返回此列表的最后一个元素。
    • public E pop() :从此列表所表示的堆栈处弹出一个元素。
    • public void push(E e) :将元素推入此列表所表示的堆栈。
    • public boolean isEmpty() :如果列表不包含元素,则返回true
      其中pop()等同于 removeFirst() ,push(E e)等同于addFirst(E e),只是更加面向对象化一点
      代码演示如下:
public class Demo02ArrayVsLinked {

    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("王俊凯");
        list.add("王源");
        list.add("易烊千玺");
        System.out.println(list); // [王俊凯, 王源, 易烊千玺]

        list.addFirst("杨洋");
        System.out.println(list); // [杨洋, 王俊凯, 王源, 易烊千玺]

        list.addFirst("张一山");
        System.out.println(list); // [张一山, 杨洋, 王俊凯, 王源, 易烊千玺]

        list.addLast("胡一天");
        System.out.println(list); // [张一山, 杨洋, 王俊凯, 王源, 易烊千玺, 胡一天]

        System.out.println("开头元素:" + list.getFirst()); // 张一山
        System.out.println("末尾元素:" + list.getLast()); // 胡一天
        System.out.println(list); // [张一山, 杨洋, 王俊凯, 王源, 易烊千玺, 胡一天]

        System.out.println("删掉的开头元素:" + list.removeFirst()); // 张一山
        System.out.println(list); // [杨洋, 王俊凯, 王源, 易烊千玺, 胡一天]
        System.out.println("删掉的开头元素:" + list.removeFirst()); // 杨洋
        System.out.println(list); // [王俊凯, 王源, 易烊千玺, 胡一天]
        System.out.println("删掉的开头元素:" + list.removeFirst()); // 王俊凯
        System.out.println(list); // [王源, 易烊千玺, 胡一天]

        System.out.println("================");
        System.out.println("删掉末尾元素:" + list.removeLast()); // 胡一天
        System.out.println(list); // [王源, 易烊千玺]
    }

}
Vector(不做重点)

和ArrayList基本一样,底层也是数组,只是线程安全,所以性能不如ArrayList快。


Interface Set<泛型>


Set的特点


  1. Set 接口中元素无序
  2. 都会以某种规则保证存入的元素不出现重复
  3. 没有索引值

Set的实现类


HashSet
  • HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性的方式依赖于: hashCode 与 equals 方法。equals负责决定对象是否相同,hashCode负责进行哈希加速。
  • HashSet是最为常用的Set集合,底层使用一种名叫“哈希表”的数据结构,特点就是特别快。底层其实是在复用HashMap。
LinkedHashSet
  • 底层也是哈希表,但是额外还有链表,用来维护先后顺序。
TreeSet
  • 有大小排序。
  • 要求实现Comparable接⼝

Interface Map<键,值>


Map特点


  • Map 中的集合称为双列集合,存放的是一对儿数据
  • Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。由equals和hashCode方法,来确定Map的键不能重复。
  • 遍历Map集合的方法一:通过keySet方法首先拿到所有的键。再根据get方法,得到每个键对应的值.
  • 遍历Map集合的方法二:
    1. 首先直接获取所有的键值对儿:entrySet
    2. 根据键值对儿获取键:getKey
    3. 根据键值对儿获取值:getValue

常用的方法:
- public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。


注意事项

  • 使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
  • 若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

  • public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
  • public Set<键> keySet() : 获取Map集合中所有的键,存储到Set集合中。
    public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)(重要)
    遍历集合方法一:
    代码如下:
public class Demo02MapKeySet {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("王宝强", "马蓉");
        map.put("贾乃亮", "李小璐");
        map.put("陈羽凡", "白百何");

        // 拿到所有的键
        Set<String> keys = map.keySet();
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key + "的老婆是" + value);
        }
        System.out.println("==========");

        Set<String> keys2 = map.keySet();
        Iterator<String> iter = keys2.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            String value = map.get(key);
            System.out.println(key + "的相好是" + value);
        }
    }

}

遍历集合方法二:

public class Demo03MapEntrySet {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("王宝强", "马蓉");
        map.put("贾乃亮", "李小璐");
        map.put("陈羽凡", "白百何");

        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "的bitch是" + value);
        }
    }

}

Map的实现类


HashMap
  • 底层有哈希表,所以查找键的速度特别快。HashSet底层就是在复用HashMap
  • 由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
  • 存储数据采用的哈希表结构,元素的存取顺序不能保证一致
  • Map的键和值数据类型可以不同
LinkedHashMap
  • 是HashMap的子类,速度也挺快,但是额外还有链表,从而维护先后顺序。
  • 通过哈希表结构可以保证的键的唯一、不重复,需要重写键的
    hashCode()方法、equals()方法。
TreeMap
  • 键带有大小排序功能
  • 注意事项:
    如果自定义的类型作为TreeMap的value,没有要求。
    但是自定义的类型作为TreeMap的key,就必须要实现Comparable接口。

例如:(Person构造略)

...
 @Override
    public int compareTo(Person o) {
        return age - o.age;
    }
...
public class Demo02TreeSetAndTreeMap {

    public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("DDD");
        set.add("BBB");
        set.add("AAA");
        set.add("CCC");
        System.out.println(set); // [AAA, BBB, CCC, DDD]
        System.out.println("=========");

        Map<String, String> mapA = new TreeMap<>();
        mapA.put("DDD", "value");
        mapA.put("BBB", "value");
        mapA.put("AAA", "value");
        mapA.put("CCC", "value");

        Set<Map.Entry<String, String>> entries = mapA.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + " - " + value);
        }
        System.out.println("=========");

        Map<Person, String> mapB = new TreeMap<>();
        mapB.put(new Person("鹿晗", 40), "北京");
        mapB.put(new Person("吴亦凡", 35), "广州");
        Set<Person> keys = mapB.keySet();
        for (Person key : keys) {
            String value = mapB.get(key);
            System.out.println(key + " - " + value);
        }
    }

}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值