Java集合基础知识整理

Java集合基础知识整理

集合与数组的区别:

  1. 长度区别:数组长度固定,集合长度可变
  2. 内容不同:数组只能是同一类型元素,集合可以存储不同类型元素
  3. 元素的数据类型不同:数组可以存储基本类型和引用类型,集合只能存储引用类型(对象)

集合继承关系图:
在这里插入图片描述

第一类:Collection集合

Collection类:

是所有Collextion集合类的超类,是一个抽象类

基本功能:
    public static void main(String[] args) {
        //创建集合对象
        Collection c = new ArrayList();
        //返回boolean
        c.add("hello");
        c.add("world");
        c.add("java");
        System.out.println("c: " + c);
        //清除所有对象
//        c.clear();
        //清除指定元素
        c.remove("hello");
        System.out.println(c);
        //判断是否存在某个元素
        System.out.println(c.contains("world"));
        //元素个数
        System.out.println(c.size());
    }
高级功能:
public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add("abc1");
        c1.add("abc2");
        c1.add("abc3");
        c1.add("abc4");
        Collection c2 = new ArrayList();
        c2.add("abc5");
        c2.add("abc6");
        c2.add("abc7");
        System.out.println(c1);
        System.out.println(c2);
        //高级功能测试
        //添加另外一个集合
        System.out.println(c1.addAll(c2)); //返回boolean
        System.out.println(c1);
        //移除一个集合中所有的元素
        Collection c3 = new ArrayList();
        c3.add("abc1");
        c3.add("abc9");
        System.out.println(c1.removeAll(c3)); //由此可见,移除集合是匹配集合中存在的值,有一个符合就返回true
        System.out.println(c1);
        //判断是否包含集合
        System.out.println(c1.containsAll(c2));//必须包含所有值才能算包含
        System.out.println(c1.containsAll(c3));
        //两个集合都有的元素,交集
        //谁调方法,谁就保存交集元素.返回值表示的是:集合是否发生过改变
        Collection c5 = new ArrayList();
        c5.add("abcd1");
        c5.add("abcd2");
        c5.add("abcd3");
        Collection c4 = new ArrayList();
        c4.add("abcd4");
        System.out.println(c5.retainAll(c4)); //ture
        System.out.println(c5); //[]
        c4.add("abcd1");
        c4.add("abcd2");
        c4.add("abcd3");
        System.out.println(c5.retainAll(c4)); //false
        System.out.println(c5);
    }
集合的遍历:
    //数组方式
    //1.先转数组
    Object[] objs = c.toArray(); 
    //2.按数组方式遍历
    for(...){...}
    
    //迭代器方式
    //创建迭代器
    Iterator it = c.iterator(); //返回接口子类对象,多态应用
    while (it.hasNext()){
        System.out.println(it.next());
    }
    //注意:对同一对象不能多次使用next方法

List接口:

基本操作同上Collection父类.

特点:
  1. 有序的集合
  2. 可以对元素的插入位置进行精确的控制
  3. 可根据元素的整数索引访问元素,并搜索元素
  4. 允许重复(与Set不同)
特有功能:
public static void main(String[] args) {
        List list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("java");
        //重写了toString方法
        System.out.println(list);
        //指定位置添加,元素位置出现在这个位置
        list.add(1, "android");
        System.out.println(list);
        //获取指定位置元素
        System.out.println(list.get(2));
        //特有循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //根据索引删除元素
        list.remove(1);
        System.out.println(list);
        //修改元素
        list.set(1, "aaa");
        System.out.println(list);
        //列表迭代器
        ListIterator lit = list.listIterator();
        while (lit.hasNext()) {
            System.out.println(lit.next());
        }
        //特有功能,获取上一个元素,若想逆向遍历,必须先正向遍历,一般无意义
        while (lit.hasPrevious()) {
            System.out.println(lit.previous());
        }
    }
注意问题:

并发修改异常:在迭代遍历中加入元素,迭代器并不知道,所以报错;迭代器遍历元素时不能修改元素.

如何解决?

  1. 迭代器迭代元素,迭代器修改元素,使用子接口ListIterator可以添加元素,新添加的元素就在迭代元素后面
  2. 集合遍历元素,集合修改元素(for循环),但元素会在最后添加
List类的三个子类:
  1. ArrayList类:底层数据结构是数组,查询快,增删慢,线程不安全,效率高
  2. Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低
  3. LinkedList:底层是链表实现,并且是双重链表,查询慢,但是增删快,线程不安全,效率高
  • 一般用Collections.synchronizedList代替LinkedList
List<String> list = Colloections.synchronizedList(new ArrayList(String);
ArrayList子类:

操作等已在Collection类中演示

Vector子类:

特有功能:

public static void main(String[] args) {
        Vector v = new Vector();
        v.addElement("hello");
        v.addElement("world");
        v.addElement("java");
        //普通遍历
        for (int i = 0; i < v.size(); i++) {
            String s = (String) v.elementAt(i);
            System.out.println(s);
        }
        //特有迭代
        Enumeration en = v.elements(); //返回的是实现类的对象
        while (en.hasMoreElements()) {
            String s = (String) en.nextElement();
            System.out.println(s);
        }
        //迭代器
        Iterator iterator = v.iterator();
        while (iterator.hasNext()) {
            String s = (String) iterator.next();
            System.out.println(s);
        }
    }
linkedList子类:

特有功能:

public static void main(String[] args) {
        LinkedList link = new LinkedList();
        link.add("hello");
        link.add("world");
        link.add("java");
        //首部添加
        link.addFirst("javaee");
        System.out.println(link);
        //尾部添加,无意义,默认就是尾部添加
        link.addLast("android");
        System.out.println(link);
        //获取第一个
        System.out.println(link.getFirst());
        //获取最后一个
        System.out.println(link.getLast());
        //移除首尾元素
        link.removeFirst();
        link.removeLast();
    }
Arrays工具类与集合转换:
        String[] strArr = {"hello", "world", "java"};
        List<String> list = Arrays.asList(strArr);
        for (String s : list) {
            System.out.println(s);
        }
        
        注意:把数组转换成集合时长度不变,本质上仍是一个数组
集合嵌套:
public static void main(String[] args) {
        ArrayList<ArrayList<String>> bigArrayList = new ArrayList<ArrayList<String>>();

        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("hello");
        list1.add("hello");
        list1.add("hello");

        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("world");
        list2.add("world");
        list2.add("world");

        bigArrayList.add(list1);
        bigArrayList.add(list2);
        
        for (ArrayList<String> strArr : bigArrayList) {
            for (String s : strArr) {
                System.out.println(s);
            }
        }
    }

Set接口:

特点:
  1. 无序(存储顺序和取出顺序不一致)
  2. 唯一(不重复)
HashSet子类:
  1. 可以重写equals方法,判断是否是相同对象
  2. 底层是哈希表
LinkedHashSet子类:

是Set的哈希表和链表实现,其它都相同

特点:

  1. 链表特性保证元素有序
TreeSet子类:

能够对元素进行某种规则进行排序

  1. 自然排序:一个类如果需要自然排序,就必须实现接口Comparable并实现compareTo()方法
  2. 比较器排序:单独创建比较类并实现接口Comparable并实现compareTo()方法

Collections工具类概述:

Collection是单列集合的顶层接口,Collections是针对集合操作的工具类,比如排序和查找等.

常见用法:
 public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(30);
        list.add(50);
        list.add(40);
        list.add(10);
        list.add(100);
        list.add(20);
        System.out.println(list);
        //排序
        Collections.sort(list);
        System.out.println(list);
        //二分查找
        System.out.println(Collections.binarySearch(list,11)); //二分查找,找不大的时候返回位置(第几个)取反
        //取反
        Collections.reverse(list);
        System.out.println(list);
        //随机置换
        Collections.shuffle(list);
        System.out.println(list);
    }

第二类:Map集合

Map集合是键值对双列集合

特点:

  1. 键是唯一的,值可重复,且一一对应
  2. 基于哈希表的Map接口实现,用来保证键的唯一性

HashMap子类:

基础功能:
    public static void main(String[] args) {
        Map<String, String> m = new HashMap<String, String>();
        System.out.println(m.put("文章","马伊琍")); //第一次赋值返回null
        System.out.println(m.put("文章","123")); //返回已存在值,并替换为新的值
        m.put("邓超","孙俪");
        System.out.println(m);

//        m.clear();//清除所有键值对元素
//        System.out.println(m.remove("文章"));//移除元素并返回值
        System.out.println(m);

        System.out.println(m.containsKey("文章")); //true
        System.out.println(m.isEmpty()); //false
        System.out.println(m.size()); //2
    }
高级功能(获取):
    public static void main(String[] args) {
        Map<String, String> m = new HashMap<String, String>();
        m.put("邓超", "孙俪");
        m.put("邓超2", "孙俪");
        m.put("邓超3", "孙俪");

        System.out.println(m.get("邓超"));

        //获取集合中所有键的集合
        Set<String> set = m.keySet();
        for (String key : set) {
            System.out.println(key);
            System.out.println(m.get(key));
        }

        //获取所有值的集合
        Collection<String> con = m.values();
        for (String value : con) {
            System.out.println(value);
        }
    }
集合遍历:
    public static void main(String[] args) {
        Map<String, String> m = new HashMap<String, String>();
        m.put("邓超1", "孙俪1");
        m.put("邓超2", "孙俪2");
        m.put("邓超3", "孙俪3");

        //方式1
        Set<String> set = m.keySet();
        for (String key : set) {
            System.out.println(m.get(key));
        }

        //方式2,获取所有键值对对象
        Set<Map.Entry<String, String>> en = m.entrySet();
        for (Map.Entry<String, String> obj : en) {
            System.out.println(obj.getKey() + "===" + obj.getValue());
        }
    }

LinkedHashMap子类:

特点:
  1. 具有可预知的迭代顺序,且唯一
  2. 支持自然排序和比较器排序
自然排序:类实现CompareTo接口,并重写compareTo方法.
public class Student implements Comparable<Student> {
     @Override
    public int compareTo(Student o) {
        int idNum = this.getId() - o.getId();
        int nameNum = idNum == 0 ? this.getName().compareTo(o.getName()) : idNum;
        return nameNum;
    }
}
比较器排序:在初始化集合的时候重写调用比较器构造方法
        TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int idNum = o1.getId() - o2.getId();
                int ageNum = idNum == 0 ? o1.getName().compareTo(o2.getName()) : idNum;
                return ageNum;

            }
        });

HashMap 和 Hashtable 的 区别?

  1. 前者线程不安全,效率高;后者线程安全,效率低
  2. 前者允许null和null值,后者不允许

List,Set,Map是否都继承了Map接口?

  1. 不是,List,Set 不继承,它们继承Collection.
  2. Map本身是一个顶层接口

集合的区别?

区别:

Collection类:单列集合

  1. List(有序,可重复):
  • ArrayList:底层是数组,查询快,增删慢,线程不安全,效率高
  • Vector:底层是数组,查询快,增删慢,线程安全,效率低
  • LinkedList:底层是链表,查询慢,增删快,线程不安全,效率高
  1. Set(无序,唯一):
  • HashSet:底层是哈希表,依赖hashCode()和equals().自定义类需要自动生成这两个方法

如何保证唯一性:
先判断hashCode是否相同,否就就添加到集合,是就再比较equals,否就添加,是就是重复不添加

-LinkedHashSet: 是HashSet的子类,底层是链表和哈希表组成,链表保证有序,哈希表保证唯一.

  • TreeSet: 底层数据结构是红黑树(是一种自平衡的二叉树,保证深度不会太深)

如何保证唯一性?
根据比较值是否为0

如何保证元素排序?
两种方式,自然排序(元素具备比较性)和比较器排序(集合具备比较性)

Map(双列集合):

注意: Map集合的数据仅仅针对键有效,与值无关

  1. HashMap:底层是哈希表,线程不安全,依赖hashCode()和equals().自定义类需要自动生成这两个方法,不支持排序

如何保证唯一性:
先判断hashCode是否相同,否就就添加到集合,是就再比较equals,否就添加,是就是重复不添加

  1. LinkedHashMap:是HashSet的子类,底层是链表和哈希表组成,链表保证有序,哈希表保证唯一.
  2. Hashtable: 线程安全的HashMap
  3. TreeMap:底层数据结构是红黑树(是一种自平衡的二叉树,保证深度不会太深),支持排序

如何保证唯一性?
根据比较值是否为0

如何保证元素排序?
两种方式,自然排序(元素具备比较性)和比较器排序(集合具备比较性)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值