集合

作者: Binary_r | 来源:发表于2019-03-26 21:36 被阅读0次

    一、集合

    1、什么是集合

    存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式。
    集合的出现就是为了持有对象。集合中可以存储任意类型的对象, 而且长度可变。在程序中有可能无法预先知道需要多少个对象, 那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题。

    2、集合和数组的区别

    数组和集合类都是容器,数组长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象数组中存储数据类型是单一的,集合中可以存储任意类型的对象。

    ①、集合类的特点

    用于存储对象,长度是可变的,可以存储不同类型的对象。

    ②、数组的缺点

    存储类型单一的数据容器,操作复杂(数组一旦声明好不可变)

    3、集合的分类
    ---|Collection: 单列集合
    ---|Collection: 单列集合
                ---|List: 有存储顺序, 可重复
                    ---|ArrayList:  数组实现, 查找快, 增删慢
                                    由于是数组实现, 在增和删的时候会牵扯到数组增容, 
    以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快
                    ---|LinkedList: 链表实现, 增删快, 查找慢
                                    由于链表实现, 增加时只要让前一个元素记住自
    己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素. 
    这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低
                    ---|Vector: 和ArrayList原理相同, 但线程安全, 效率略低
                           和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低
                ---|Set: 无存储顺序, 不可重复
                    ---|HashSet
                    ---|TreeSet
                    ---|LinkedHashSet
    ---| Map: 键值对
            ---|HashMap
            ---|TreeMap
            ---|HashTable
            ---|LinkedHashMap
    

    二、集合类(Collection)

    Collection接口有两个子接口:
    List(链表|线性表)
    Set(集)

    java.util.Collection
            ---| Collection     描述所有接口的共性
                ----| List接口    可以有重复元素的集合
                ----| Set  接口   不可以有重复元素的集合
    
    2.1. Collection接口的共性方法
    增加:
            1:add() 将指定对象存储到容器中
                          add 方法的参数类型是Object 便于接收任意对象
            2:addAll() 将指定集合中的元素添加到调用该方法和集合中
    删除:
            3:remove() 将指定的对象从集合中删除
            4:removeAll() 将指定集合中的元素删除
    修改
            5:clear() 清空集合中的所有元素
    判断
            6:isEmpty() 判断集合是否为空
            7:contains() 判断集合何中是否包含指定对象
                
            8:containsAll() 判断集合中是否包含指定集合
                                使用equals()判断两个对象是否相等  
    获取:   9:int size()    返回集合容器的大小
    
    转成数组10: toArray()   集合转换数组
    
    练习:集合中添加自定义对象
    class Person {
        private String name;
        private int age;
        public Person() {
    
        }
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int hashCode() {
            return this.name.hashCode() + age;
        }
        @Override
        public boolean equals(Object obj) {
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age;
        }
        @Override  
        public String toString() {
            return "Person :name=" + name + ", age=" + age;
        }
    
    }
    
    public static void main(String[] args) {
            Person p1 = new Person("张三", 19);
            Person p2 = new Person("李四", 20);
            Person p3 = new Person("王五", 18);
            Collection list = new ArrayList();
            list.add(p1);
            list.add(p2);
            list.add(p3);
            // isEmpty() 判断集合是否为空
            boolean empty = list.isEmpty();
            System.out.println(empty);
            // 返回集合容器的大小
            int size = list.size();
            System.out.println(size);
             // contains()判断集合何中是否包含指定对象
            boolean contains = list.contains(p1);
            System.out.println(contains);
    
            // remove(); 将指定的对象从集合中删除
            list.remove(p1);
            
            // clear() 清空集合中的所有元素
            list.clear();
            System.out.println(list);
    
        }
    
    2.2.List

    元素可以重复,允许在指定位置插入元素,并通过索引来访问元素

    2.2.1 List集合特有的方法
    1:增加
            void add(int index, E element) 指定位置添加元素            
            boolean addAll(int index, Collection c) 指定位置添加集合  
    2:删除
            E remove(int index) 删除指定位置元素
    
    3:修改
            E set(int index, E element)    返回的是需要替换的集合中的元素
    4:查找:
            E get(int index)             注意: IndexOutOfBoundsException
            int indexOf(Object o)         // 找不到返回-1
            lastIndexOf(Object o) 
    5:求子集合
             List<E> subList(int fromIndex, int toIndex) // 不包含toIndex
    
    2.2.2. ArrayList

    ArrayList 底层采用数组实现,默认10。每次增长60%,((oldCapacity * 3)/2 + 1) 查询快,增删慢。

    练习:去除ArrayList集合中重复元素

    1:存入字符串元素
    2:存入自定义对象元素(如Perosn对象)
    原理:
    循环遍历该集合,每取出一个放置在新的集合中,放置之前先判断新的集合是否以包含了新的元素。

    public class Demo6 {
        public static void main(String[] args) {
            ArrayList arr = new ArrayList();
            Person p1 = new Person("jack", 20);
            Person p2 = new Person("rose", 18);
            Person p3 = new Person("rose", 18);
            arr.add(p1);
            arr.add(p2);
            arr.add(p3);
            System.out.println(arr);
            ArrayList arr2 = new ArrayList();
            for (int i = 0; i < arr.size(); i++) {
                Object obj = arr.get(i);
                Person p = (Person) obj;
                if (!(arr2.contains(p))) {
                    arr2.add(p);
                }
            }
            System.out.println(arr2);
        }
    }
    
    class Person {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public boolean equals(Object obj) {
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age;
        }
        @Override
        public String toString() {
            return "Person@name:" + this.name + " age:" + this.age;
        }
    }
    
    
    2.2.3. LinkedList

    LinkedList 底层采用链表实现,增删快,查询慢。
    特有方法:

    1:方法介绍
                addFirst(E e) //添加到第一位
                addLast(E e) //添加到末尾
                getFirst() //获取第一位元素的内容
                getLast() //获取最后一位元素的内容
                removeFirst() //删除第一位元素
                removeLast() //删除最后一位元素
                如果集合中没有元素,获取或者删除元素抛异常:NoSuchElementException
    2:数据结构
                    1:栈 (1.6)
                        先进后出
                        push() 
                        pop()
                    2:队列(双端队列1.5)
                        先进先出
                        offer()
                        poll()
    3:返回逆序的迭代器对象      
    descendingIterator()   返回逆序的迭代器对象
    
    2.3. 迭代器 Iterable

    简洁:Jdk1.5之后添加的新接口, Collection的父接口. 实现了Iterable的类就是可迭代的.并且支持增强for循环。该接口只有一个方法即获取迭代器的方法iterator() 可以获取每个容器自身的迭代器Iterator。

    Iterator接口定义的方法
    Itreator    该接口是集合的迭代器接口类,定义了常见的迭代方法
        1:boolean hasNext() 
                        判断集合中是否有元素,如果有元素可以迭代,就返回true。
        2: E next()  
                        返回迭代的下一个元素,注意: 如果没有下一个元素时,调用
    next元素会抛出NoSuchElementException
    
        3: void remove()
                        从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
    
    迭代器的遍历
    while循环
    public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 增加:add() 将指定对象存储到容器中
            list.add("计算机网络");
            list.add("现代操作系统");
            list.add("java编程思想");
            list.add("java核心技术");
            list.add("java语言程序设计");
            System.out.println(list);
            Iterator it = list.iterator();
            while (it.hasNext()) {
                String next = (String) it.next();
                System.out.println(next);
            }
        }
    
    for循环
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Demo2 {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 增加:add() 将指定对象存储到容器中
            list.add("计算机网络");
            list.add("现代操作系统");
            list.add("java编程思想");
            list.add("java核心技术");
            list.add("java语言程序设计");
            System.out.println(list);
    
            for (Iterator it = list.iterator(); it.hasNext();) {
                 //迭代器的next方法返回值类型是Object,所以要记得类型转换。
                String next = (String) it.next();
                System.out.println(next);
            }
        }
    }
    
    使用迭代器清空集合
    public class Demo1 {
        public static void main(String[] args) {
            Collection coll = new ArrayList();
            coll.add("aaa");
            coll.add("bbb");
            coll.add("ccc");
            coll.add("ddd");
            System.out.println(coll);
            Iterator it = coll.iterator();
            while (it.hasNext()) {
                it.next();
                it.remove();
            }
            System.out.println(coll);
        }
    }
    

    细节一:
    如果迭代器的指针已经指向了集合的末尾,那么如果再调用next()会返回NoSuchElementException异常
    细节二:
    如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException

    注意在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。

    List特有的迭代器ListIterator
    ListIterator Iterator子接口 List专属的迭代器
               add(E e)    将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
               void set(E o)   用指定元素替换 next 或 previous 返回的最后一个元素
               hasPrevious()    逆向遍历列表,列表迭代器有多个元素,则返回 true。
               previous()       返回列表中的前一个元素。
    

    Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。对于 Iterator 的子接口ListIterator 在迭代list 集合时,还可以对元素进行添加(add(obj)),修改set(obj)的操作。

    倒序遍历
    import java.util.ArrayList;
    import java.util.ListIterator;
    
    public class Demo2 {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();
            // 增加:add() 将指定对象存储到容器中
            list.add("计算机网络");
            list.add("现代操作系统");
            list.add("java编程思想");
            list.add("java核心技术");
            list.add("java语言程序设计");
            System.out.println(list);
            // 获取List专属的迭代器
            ListIterator lit = list.listIterator();
            while (lit.hasNext()) {
                String next = (String) lit.next();
                System.out.println(next);
            }
            System.out.println("***************");
            while (lit.hasPrevious()) {
                String next = (String) lit.previous();
                System.out.println(next);
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:集合

          本文链接:https://www.haomeiwen.com/subject/xzanvqtx.html