Java集合

什么是集合:

对象的容器,定义了对多个对象进行操作,类似数组的功能。

集合和数组的区别:

数组长度固定,集合长度不固定
数组可以存储基本类型和引用类型,集合只能存储引用类型
位置: java.util.*

Collection 体系集合

图片1.png

Collection父接口

List 接口

public static void main(String[] args) {
        //创建集合对象
        List list = new ArrayList<>();
        //1添加元素
        list.add("苹果");
        list.add("小米");
        list.add("华为");
        list.add("OPPO");
        list.add("Vivo");
        System.out.println("元素个数:" +list.size());
        System.out.println(list.toString());
        //2.删除元素
        System.out.println("-----使用remove(o)方法删除苹果");
        System.out.println("-----使用remove(index)方法删除下标为0的元素------");
        list.remove("苹果");//删除方式1
        list.remove(0);//删除方式2
        System.out.println(list.toString());
        //3.遍历
        //3.1 for
        System.out.println("-----使用for循环迭代-----");
        for (int i = 0; i < list.size() ; i++) {
            System.out.println(list.get(i));
        }
        //3.2增强for
        System.out.println("-----使用增强for循环迭代-----");
        for (Object o : list) {
            System.out.println(o);
        }
        //3.3迭代器
     
 System.out.println("-----使用迭代器迭代------");
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        //3,4使用列表迭代器和iterator的区别
        ListIterator lit = list.listIterator();
        System.out.println("------使用列表迭代器从前往后遍历-------");
        while (lit.hasNext()){
            System.out.println(lit.nextIndex() + ":" +lit.next());
        }
        System.out.println("------使用列表迭代器从后往前遍历-------");
        while (lit.hasPrevious()){
            System.out.println(lit.previousIndex() + ":" + lit.previous());
        }
        //4.判断
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());
        System.out.println(list.indexOf("OPPO"));
    }
ArrayList:
  • DEFAULT_CAPACITY = 10; 默认容量
    注意:如果没有向集合中添加任何元素容为0,添加任意一个元素之后容量为10
    每次扩容大写是原来的1.5倍
  • ELEMENTDATA 存放元素的数组
  • Size 实际的元素个数
  • add() 添加元素
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
}

subList()

        //3.补充方法sublist,返回子集合,含头不含尾
        List subList = list.subList(1, 3);
        System.out.println(subList.toString());

ArrayList
数组结构实现,查询快,增删慢
运行效率快、线程不安全

public static void main(String[] args) {
        //创建集合
        ArrayList<Object> arrayList = new ArrayList<>();
        //1,添加元素
        Student s1 = new Student("刘德华", 22);
        Student s2 = new Student("郭富城", 24);
        Student s3 = new Student("梁朝伟", 23);
        Student s4 = new Student("黎明", 23);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);
        System.out.println("元素个数:" + arrayList.size());
        System.out.println(arrayList.toString());
        //2.删除操作 重写equals方法
        arrayList.remove(new Student("刘德华",20));//equals(this == obj)
        arrayList.remove(s1);
        System.out.println("删除之后:" + arrayList.size());
        //3.1遍历元素
        System.out.println("=====使用for循环进行遍历=====");
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
        Iterator<Object> it = arrayList.iterator();
        while(it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        //3.2列表迭代器
        System.out.println("-------使用列表迭代器顺序遍历元素------");
        ListIterator<Object> lit= arrayList.listIterator();
        while(lit.hasNext()){
            System.out.println(lit.nextIndex() + " :" + lit.next()) ;
        }
        System.out.println("-------使用列表迭代器逆序遍历元素------");
        while(lit.hasPrevious()){
            System.out.println(lit.previousIndex() + " :" + lit.previous());
        }
        //4.判断
        System.out.println(arrayList.contains(new Student("刘德华", 22)));
        System.out.println(arrayList.isEmpty());
        //5.查找
        System.out.println(arrayList.indexOf(new Student("黎明", 23)));

    }

Vector(向量):
数组结构实现、查询快、增删慢
运行效率慢,线程安全
LinkedList:
链表结构实现,增删快,查询慢

public static void main(String[] args) {
        //1.创建元素
        LinkedList<Object> linkedList = new LinkedList<>();
        Student s1 = new Student("张三",19);
        Student s2 = new Student("李四",20);
        Student s3 = new Student("王五",23);
        Student s4 = new Student("刘六",24);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        linkedList.add(s4);
        System.out.println(linkedList.toString());
        //删除元素
        System.out.println(linkedList.size());
        linkedList.remove(new Student("李四",20));//需要重写equals
        linkedList.remove("删除之后:" + linkedList.size());
//        linkedList.clear();
        //遍历元素
        //3.1for 循环
        System.out.println("=====使用for循环进行遍历=====");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        //3.2迭代器遍历
        System.out.println("=====使用迭代器进行遍历=====");
        Iterator<Object> it = linkedList.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //3.3增强for循环
        System.out.println("使用增强for循环进行遍历");
        for (Object o : linkedList) {
            Student s = (Student)o;
            System.out.println(s.toString());
        }
        //3.4列表迭代器
        ListIterator<Object> lit = linkedList.listIterator();
        while(lit.hasNext()){
            System.out.println(lit.nextIndex()+ " :" + lit.next());
        }
        System.out.println("===============");
        while(lit.hasPrevious()){
            System.out.println(lit.previousIndex() + " : " + lit.previous());
        }
        //4.判断
        System.out.println(linkedList.contains(new Student("李四",20)));
        System.out.println(linkedList.isEmpty());
        //5.查找
        System.out.println(linkedList.indexOf(new Student("王五",23)));
    }

不同结构实现方式
ArraylistArrayList:必须开辟连续空间,查询快,增删慢。LinkedList:无需开辟连续空间,查询慢,增删快。

泛型

参数化类型
常见类型 泛型类、泛型接口、泛型方法

public class MyGeneric<T> {
    //使用泛型
    //1.使用泛型 注意不能实例化
    T t;
    //2 作为方法的参数
    public void show(T t){
        System.out.println(t);
    }
    //3.泛型作为方法的返回值
    public T  getT(){
        return t;
    }
}

语法
<T,E,K,V>
好处:(1)提高代码的重用性
(2)防止类型转换异常,提高代码的安全牲
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:编译时即可检查,而非运行时抛出异常。访问时,不必类型转换(拆箱)。
不同泛型之间引用不能相互赋值,泛型不存在多态。

set 接口

特点:(1) 无序,没有下标 (2)不能重复

   public static void main(String[] args) {
        //创建集合
        Set<String> set =  new HashSet<>();
        //1.添加数据
        set.add("curry");
        set.add("james");
        set.add("green");
        set.add("poor");
        set.add("poor");
        System.out.println("数据个数" + set.size());
        System.out.println(set.toString());
        //2.删除数据
        set.remove("poor");
//        set.clear();
        //3.遍历
        //3.1增强for
        System.out.println("=======使用增强for循环======");
        for (String s : set) {
            System.out.println(s);
        }
        //3.2迭代器
        System.out.println("=======使用迭代器======");
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //4.判断
        System.out.println(set.isEmpty());
        System.out.println(set.contains("curry"));
    }

HashSet

基于HashCode实现元素不重复。
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

public static void main(String[] args) {
        //创建集合
        HashSet<Person> persons = new HashSet<>();
        Person p1 = new Person("curry",34);
        Person p2 = new Person("james",37);
        Person p3 = new Person("green",33);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        System.out.println("元素个数:"+ persons.size());
        System.out.println(persons.toString());
        //删除操作
        persons.remove(p1);
        persons.remove(new Person("curry",34));
        System.out.println("删除元素个数:"+ persons.size());
        //遍历
        //3.1适应增强for
        for (Person person : persons) {
            System.out.println(person);
        }
        System.out.println("============");
        //3.2迭代器
        Iterator<Person> it = persons.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //4.判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.contains(new Person("curry",34)));

TreeSet

  • 基于排序顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素
  • 存储结构:红黑树
public static void main(String[] args) {
        TreeSet<Person> persons =new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge() - o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0? n2:n1;
            }
        });
        //1.添加元素
        Person p1 = new Person("curry",34);
        Person p2 = new Person("james",37);
        Person p3 = new Person("green",33);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        System.out.println("元素个数:" + persons.size());// 如果不重写comparable接口 ClassCastException  cannot be cast to java.lang.Comparable
        System.out.println(persons.toString());
        //删除
        persons.remove(p2);
        System.out.println("元素个数:" + persons.size());
        //遍历元素
        for (Person person : persons) {
            System.out.println(person.toString());
        }
        Iterator<Person> it = persons.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.contains(new Person("curry",34)));

    }
存储过程

(1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。(2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表

Map接口

Map接口的特点:

  1. 用于存储任意键值对
  2. 无序、无下标、不允许重复(唯一)
  3. 值:无序、无下标、允许重复

Map集合的使用

//创建Map集合
        Map<String,String> map =  new HashMap<String,String>();
        //1.添加数据
        map.put("cn","中国");
        map.put("uk","英国");
        map.put("usa","美国");
        System.out.println("元素个数" + map.size());
        System.out.println(map.toString());
        //2.删除元素
//        map.remove("usa");
        System.out.println(map.size());
        //3.遍历
        //3.1使用keySet()1.先拿到所有key的set集合,再通过get获取value值
        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            System.out.println(key + map.get(key));
        }
        System.out.println("==========");
        for (String key : map.keySet()) {
            System.out.println(key + map.get(key));
        }
        //3.2使用entrySet()方法 1.得到键值对映射集合 2.再通过getKey()获取键 getValue()获取值 效率较高
        System.out.println("========使用entrySet()方法=========");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            System.out.println(entry.getKey()+ entry.getValue());
        }
        System.out.println("===========");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + entry.getValue());
        }
        //4.判断
        map.containsKey("cn");
        map.containsValue("韩国");

HashMap的使用

public static void main(String[] args) {
       //创建集合  刚创建好hashmap 之后没有添加元素 table = null size =  0 节省空间
        HashMap<Student ,String> students = new  HashMap<Student ,String>();
        //添加元素
        Student s1 =  new Student("curry",100);
        Student s2 =  new Student("James",101);
        Student s3 =  new Student("kobe",102);
        Student s4 =  new Student("zff",103);
        students.put(s1,"金州");
        students.put(s2,"Los");
        students.put(s3,"Los");
        students.put(s4,"厦门");
        students.put(new Student("curry",100),"金州");//若想要去重,则重写hashcode()和equals()
        System.out.println("元素个数:" + students.size());
        System.out.println(students.toString());
        //删除元素
//        students.remove(s4);
//        students.remove(s2,"Los");
        //3.1 使用keySet()方法遍历元素
        System.out.println("========= 使用keySet()方法遍历元素========");
        for (Student key : students.keySet()) {
            System.out.println(key +  students.get(key));
        }
        //3.2使用entrySet()方法遍历元素
        System.out.println("======== 使用entrySet()方法遍历元素========");
        for (Map.Entry<Student, String> entry : students.entrySet()) {
            System.out.println(entry.getKey() + entry.getValue());
        }
        //4.判断
        System.out.println(students.containsKey(s1));
        System.out.println(students.containsValue("北京"));

    }

TreeMap的使用

 public static void main(String[] args) {
        //创建集合
        //因为是存储结构是红黑树需要比较  cannot be cast to java.lang.Comparable 需要 1.重写Comparable接口或者2.改造器匿名内部类
//        TreeMap<Student,String> treeMap  = new TreeMap<Student ,String>(new Comparator<Student>() {
//            @Override
//            public int compare(Student o1, Student o2) {
//                int n1 = o1.getName().compareTo(o2.getName());
//                int n2 =  o1.getStuNo() - o2.getStuNo();
//                return n2 == 0 ? n1:n2;
//            }
//        });
        TreeMap<Student,String> treeMap = new TreeMap<Student,String>();
        Student s1 =  new Student("curry",200);
        Student s2 =  new Student("James",6);
        Student s3 =  new Student("kobe",24);
        Student s4 =  new Student("zff",47);
        treeMap.put(s1,"金州");
        treeMap.put(s2,"Los");
        treeMap.put(s3,"Los");
        treeMap.put(s4,"厦门");
        System.out.println("元素个数:" + treeMap.size());
        System.out.println(treeMap.toString());
        //2.删除元素
        treeMap.remove(s1);
        //3.遍历元素
        System.out.println("=========使用keySet遍历元素=======");
        for (Student key : treeMap.keySet()) {
            System.out.println( key + treeMap.get(key));
        }
        System.out.println("=========使用entrySet遍历元素=======");
        for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + entry.getValue());
        }
        //4.判断
        System.out.println(treeMap.containsKey(s1));
        System.out.println(treeMap.containsKey(s4));
    }

class =>HashMap=>interface Map
class=> TreeMap=> interface SortMap=>interface Map
hashmap源码分析

1. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//hashMap的初始容量大小
2. static final int MAXIMUM_CAPACITY = 1 << 30;//hashMap的数组最大容量
 3. static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
4. static final int TREEIFY_THRESHOLD = 8;//jdk 当链表长度大于8时,调整为红黑树
 5. static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8,当链表长度小于6时,形成链表
6. static final int MIN_TREEIFY_CAPACITY = 64;//jik1.8,当链表长度大于8时,并且集合元素个数大于等于64时,调整为红黑树
7. size 元素个数

总结:

  • HashMap刚创建时,table是null,当添加第一个元素之后,为了节省空间,Table容量调整为16
  • 当元素个数大于阈值(16*0.75 =12时,会出现扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
  • jdk1.8,当链表长度大于8时,并且集合元素个数大于等于64时,调整为红黑树,目的提高执行效率
  • Jdk1.8之后 当链表长度小于6时,调整为链表
  • Jdk1.8以前,链表是头插入,jdk 1.8之后,链表是尾插入
    Hashmap 和 HashSet 的关系

HashSet使用 Hashmap的key
TreeSet 使用 TreeMap 的entrySet

Collections方法

  • Sort()
  • binarySearch()
  • Copy()
  • Reverse()
  • Shuffle()
  • 集合转成数组 toarray()
  • 数组转成集合 Arrays.aslist()
public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(24);
        list.add(77);
        list.add(10);
        list.add(23);
        list.add(30);
        //sort排序
        System.out.println("排序之前:" + list.toString());
        Collections.sort(list);
        System.out.println("排序之前:" + list.toString());
        //binarySearch 大于0 表示找到了 小于0表示没有找到
        int n1 = Collections.binarySearch(list, 24);
        int n2 = Collections.binarySearch(list, 13);
        System.out.println(n1);
        System.out.println(n2);
//         List<Integer> dest =  new ArrayList<Integer>(list.size());
//        for (int i = 0; i < list.size(); i++) {
//            dest.add(0);
//        }
        List<Integer> dest = Arrays.asList(new Integer[list.size()]);
        Collections.copy(dest,list);
        System.out.println(dest.toString());
        //reverse反转
        Collections.reverse(list);
        System.out.println("反转之后:" + list.toString());
        //shuffle 打乱
        Collections.shuffle(list);
        System.out.println("打乱之后:" + list.toString());
        //list转成数组
        Integer[] arr = list.toArray(new Integer[0]);
        System.out.println(arr.length);
        System.out.println(Arrays.toString(arr));
        //数组转成集合
        String[] names = {"张三", "李四","王五" };
        List<String> list2 = Arrays.asList(names);
        System.out.println(list2);
        //注意:数组转成集合后不能添加和删除
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,820评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,648评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,324评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,714评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,724评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,328评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,897评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,804评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,345评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,431评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,561评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,238评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,928评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,417评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,528评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,983评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,573评论 2 359

推荐阅读更多精彩内容

  • 一、集合概述 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。 和数组的区别:数组长度 固...
    yjtuuige阅读 216评论 1 2
  • 一、集合入门总结 集合框架: Java中的集合框架大类可分为Collection和Map;两者的区别: 1、Col...
    程序员欧阳阅读 11,575评论 2 61
  • 集合分类 Collection集合 单列集合, 直接存储对象的引用 Map集合 双列集合, 使用key-value...
    一介星辰阅读 286评论 0 0
  • 简介 集合框架:用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包...
    JourWon阅读 812评论 0 13
  • 集合的特点: 存储的数据量可变 存储的数据类型可变(通过泛型可以添加不同类型的数据) 只能存储引用类型上述三点都是...
    LeoFranz阅读 300评论 0 0