• Java集合(续)


    java学习笔记 --- 集合

    1、定义:集合是一种容器,专门用来存储对象

       数组和集合的区别?
          A:长度区别
           数组的长度固定    集合长度可变
             B:内容不同
           数组存储的是同一种类型的元素
           而集合可以存储不同类型的元素
         C:元素的数据类型问题 
          数组可以存储基本数据类型,也可以存储引用数据类型
          集合只能存储引用类型

    2、集合的继承体系结构  
      由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,提供不同的存储和遍历功能.最终就形成了集合的继承体系结构图。
       Collection<E>
           |--List (有序、重复)
               |--ArrayList(数组结构查询快,增删慢线程不安全,效率高)
               |--Vector(数组结构)
                |--LinkedList(链表结构查询慢,增删快线程不安全,效率高)
           |--Set(部分无序序、不重复)
               |--HashSet (哈希表结构,无序元素不重复重写hashCode() equals()方法)

                                 |--LinkedHashSet(哈希表+链表结构、存取有序不重复线程不安全)
               |--TreeSet (-黑树的数据结构,实现Comparable接口有序集合、自然排序)

     

    3Collection集合:集合体系的顶层接口

        3.1 Collection的功能概述:
          1:添加功能
            boolean add(Object obj):添加一个元素
            boolean addAll(Collection c):添加一个集合的元素
          2:删除功能
            void clear():移除所有元素
            boolean remove(Object o):移除一个元素
            boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)
          3:判断功能
            boolean contains(Object o):判断集合中是否包含指定的元素
            boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)
            boolean isEmpty():判断集合是否为空
          4:长度功能
             int size():元素的个数
          5:交集功能
             boolean retainAll(Collection c):两个集合都有的元素

                6:把集合转换为数组,可以实现集合的遍历
             Object[] toArray()

    1  public class CollectionDemo {

           public static void main(String[] args) {

            // 测试不带All的方法

            // 创建集合对象

            // Collection c = new Collection(); //错误,因为接口不能实例化

            Collection c = new ArrayList();

            // boolean add(Object obj):添加一个元素

            // System.out.println("add:"+c.add("hello"));

            c.add("hello");

            c.add("world");

            c.add("java");

            // void clear():移除所有元素

            // c.clear();

            // boolean remove(Object o):移除一个元素

            // System.out.println("remove:" + c.remove("hello"));

            // System.out.println("remove:" + c.remove("javaee"));

            // boolean contains(Object o):判断集合中是否包含指定的元素

            // System.out.println("contains:"+c.contains("hello"));

            // System.out.println("contains:"+c.contains("android"));

            // boolean isEmpty():判断集合是否为空

            // System.out.println("isEmpty:"+c.isEmpty());

     

            //int size():元素的个数

            System.out.println("size:"+c.size())

            System.out.println("c:" + c);

        }

    }

     

    2  public class CollectionDemo2 {

           public static void main(String[] args) {

            // 创建集合1

            Collection c1 = new ArrayList();

            c1.add("abc1");

            c1.add("abc2");

            c1.add("abc3");

            c1.add("abc4");

            // 创建集合2

            Collection c2 = new ArrayList();

           // c2.add("abc1");

           // c2.add("abc2");

           // c2.add("abc3");

           // c2.add("abc4");

            c2.add("abc5");

            c2.add("abc6");

            c2.add("abc7");

     

            // boolean addAll(Collection c):添加一个集合的元素

            // System.out.println("addAll:" + c1.addAll(c2));

            

            //boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有)

            //只要有一个元素被移除了,就返回true。

            //System.out.println("removeAll:"+c1.removeAll(c2));

     

            //boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有)

            //只有包含所有的元素,才叫包含

            // System.out.println("containsAll:"+c1.containsAll(c2));

            

            //boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?

            //假设有两个集合A,B。

            //A对B做交集,最终的结果保存在A中,B不变。

            //返回值表示的是A是否发生过改变。

            System.out.println("retainAll:"+c1.retainAll(c2));

            

            System.out.println("c1:" + c1);

            System.out.println("c2:" + c2);

        }

    }

    集合的遍历Iterator增强for循环

     * 其实就是依次获取集合中的每一个元素。

     * Object[] toArray():把集合转成数组,可以实现集合的遍历

     */public class CollectionDemo3 {

        public static void main(String[] args) {

            // 创建集合对象

            Collection c = new ArrayList();

            // 添加元素

            c.add("hello"); // Object obj = "hello"; 向上转型

            c.add("world");

            c.add("java");

            // 遍历

            // Object[] toArray():把集合转成数组,可以实现集合的遍历

            Object[] objs = c.toArray();

            for (int x = 0; x < objs.length; x++) {

                // System.out.println(objs[x]);

                // 我知道元素是字符串,我在获取到元素的同时,还想知道元素的长度。

                // System.out.println(objs[x] + "---" + objs[x].length());

                // 上面的实现不了,原因是Object中没有length()方法

                // 我们要想使用字符串的方法,就必须把元素还原成字符串

                // 向下转型

                String s = (String) objs[x];

                System.out.println(s + "---" + s.length());

            }

        }

    }

     3.2、Iterator iterator():迭代器,集合的专用遍历方式
         Object next():获取元素,并移动到下一个位置。
         NoSuchElementException:没有这样的元素,因为你已经找到最后了。
         boolean hasNext():如果仍有元素可以迭代,则返回 true。

    public class IteratorDemo {

        public static void main(String[] args) {

            // 创建集合对象

            Collection c = new ArrayList();

            // 创建并添加元素

            // String s = "hello";

            // c.add(s);

            c.add("hello");

            c.add("world");

            c.add("java");

            // Iterator iterator():迭代器,集合的专用遍历方式

            Iterator it = c.iterator(); // 实际返回的肯定是子类对象,这里是多态

            while (it.hasNext()) {

                // System.out.println(it.next());

                String s = (String) it.next();

                System.out.println(s);

            }

        }

    }

    3.3、在使用集合时需要注意一下几点:

      1、集合中存储其实都是对象的地址。

    2、集合中可以存储基本数值吗?不行,但是jdk1.5以后可以这么写,但是存储的还

    3、存储时提升了Object。取出时要使用元素的特有内容必须向下转型。

        4List集合:存储的元素是有序的(存储和取出的元素一致),带索引的,可重复的。
        4.1List集合的特有功能:
            A:添加功能
               void add(int index,Object element):在指定位置添加元素
            B:获取功能
               Object get(int index):获取指定位置的元素
            C:列表迭代器
              ListIterator listIterator()List集合特有的迭代器
            D:删除功能
              Object remove(int index):根据索引删除元素,返回被删除的元素
            E:修改功能
               Object set(int index,Object element):根据索引修改元素,返回被修饰的元素 

    public class ListDemo {

        public static void main(String[] args) {

            // 创建集合对象

            List list = new ArrayList();

            // 添加元素

            list.add("hello");

            list.add("world");

            list.add("java");

            // void add(int index,Object element):在指定位置添加元素

            // list.add(1, "android");//没有问题

            // IndexOutOfBoundsException

            // list.add(11, "javaee");//有问题

            // list.add(3, "javaee"); //没有问题

            // list.add(4, "javaee"); //有问题

            // Object get(int index):获取指定位置的元素

            // System.out.println("get:" + list.get(1));

            // IndexOutOfBoundsException

            // System.out.println("get:" + list.get(11));

     

            // Object remove(int index):根据索引删除元素,返回被删除的元素

            // System.out.println("remove:" + list.remove(1));

            // IndexOutOfBoundsException

            // System.out.println("remove:" + list.remove(11));

            // Object set(int index,Object element):根据索引修改元素,返回被修饰的元素

            System.out.println("set:" + list.set(1, "javaee"));

            System.out.println("list:" + list);

        }

    }

    ▶List集合的特有遍历功能:

     *         size()和get()方法结合使用

     */public class ListDemo2 {

        public static void main(String[] args) {

            // 创建集合对象

            List list = new ArrayList();

            // 添加元素

            list.add("hello");

            list.add("world");

            list.add("java");

            // Object get(int index):获取指定位置的元素

            // System.out.println(list.get(0));

            // System.out.println(list.get(1));

            // System.out.println(list.get(2));

            // IndexOutOfBoundsException

            // System.out.println(list.get(3));

            // 用循环改进

            // for (int x = 0; x < 3; x++) {

            // System.out.println(list.get(x));

            // }

            // 如果元素过多,数起来就比较麻烦,所以我们使用集合的一个长度功能:size()

            // 最终的遍历方式就是:size()和get()

            for (int x = 0; x < list.size(); x++) {

                // System.out.println(list.get(x));

                String s = (String) list.get(x);

                System.out.println(s);

            }

        }

    }

    列表迭代器:

     *  ListIterator listIterator():List集合特有的迭代器

     *  该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。

     * 特有功能:

     *     Object previous():获取上一个元素

     *     boolean hasPrevious():判断是否有元素

     *     注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。

     */public class ListIteratorDemo {

        public static void main(String[] args) {

            // 创建List集合对象

            List list = new ArrayList();

            list.add("hello");

            list.add("world");

            list.add("java");

            // ListIterator listIterator()

            ListIterator lit = list.listIterator(); // 子类对象

            // while (lit.hasNext()) {

            // String s = (String) lit.next();

            // System.out.println(s);

            // }

            // System.out.println("-----------------");

            // System.out.println(lit.previous());

            // System.out.println(lit.previous());

            // System.out.println(lit.previous());

            // NoSuchElementException

            // System.out.println(lit.previous());

     

            while (lit.hasPrevious()) {

                String s = (String) lit.previous();

                System.out.println(s);

            }

            System.out.println("-----------------");

            // 迭代器

            Iterator it = list.iterator();

            while (it.hasNext()) {

                String s = (String) it.next();

                System.out.println(s);

            }

            System.out.println("-----------------");

        }

    }

    ▶4.2List的子类特点
         ArrayList:
              底层数据结构是数组,查询快,增删慢。
              线程不安全,效率高。
         Vector:
              底层数据结构是数组,查询快,增删慢。
              线程安全,效率低。
        LinkedList:
              底层数据结构是链表,查询慢,增删快。
              线程不安全,效率高。
      
         List有三个儿子,我们到底使用谁呢?
           看需求(情况)
                    要安全吗?
                要:Vector(即使要安全,也不用这个了,后面有替代的)
                不要:ArrayList或者LinkedList
              查询多:ArrayList
              增删多:LinkedList
                      如果你什么都不懂,就用ArrayList

    ▶4.3ArrayList集合    

    public class ArrayListDemo {

        public static void main(String[] args) {

            // 创建集合对象

            ArrayList array = new ArrayList();

            // 创建元素对象,并添加元素

            array.add("hello");

            array.add("world");

            array.add("java");

            // 遍历

            Iterator it = array.iterator();

            while (it.hasNext()) {

                String s = (String) it.next();

                System.out.println(s);

            }

            System.out.println("-----------");

            for (int x = 0; x < array.size(); x++) {

                String s = (String) array.get(x);

                System.out.println(s);

            }

        }

    }

    ▶4.4Vector集合

    Vector的特有功能:

     * 1:添加功能

     *      public void addElement(Object obj)      相当于add()

     * 2:获取功能

     *     public Object elementAt(int index)      相当于get()

     *     public Enumeration elements()          相当于Iterator iterator()

     *     boolean hasMoreElements()               hasNext()

     *     Object nextElement()                    next()

     * JDK升级的原因:

     *         A:安全

     *         B:效率

     *         C:简化书写

     */public class VectorDemo {

        public static void main(String[] args) {

            // 创建集合对象

            Vector v = new Vector();

            // 添加功能

            v.addElement("hello");

            v.addElement("world");

            v.addElement("java");

            // 遍历

            for (int x = 0; x < v.size(); x++) {

                String s = (String) v.elementAt(x);

                System.out.println(s);

            }

            System.out.println("------------------");

     

            Enumeration en = v.elements(); // 返回的是实现类的对象

            while (en.hasMoreElements()) {

                String s = (String) en.nextElement();

                System.out.println(s);

            }

        }

    }

    ▶4.5、LinkedList集合

     LinkedList的特有功能:

     *         A:添加功能

     *             public void addFirst(Object e)给头部添加元素

     *             public void addLast(Object e)给尾部添加元素

     *         B:获取功能

     *             public Object getFirst()获取头部元素

     *             public Obejct getLast()获取尾部元素

     *         C:删除功能

     *             public Object removeFirst()获取头部元素,并删除头部元素

     *             public Object removeLast()获取尾部元素,并删除尾部元素

     */public class LinkedListDemo {

        public static void main(String[] args) {

            // 创建集合对象

            LinkedList link = new LinkedList();

            // 添加元素

            link.add("hello");

            link.add("world");

            link.add("java");

     

            // public void addFirst(Object e)

            // link.addFirst("javaee");

            // public void addLast(Object e)

            // link.addLast("android");

            // public Object getFirst()

            // System.out.println("getFirst:" + link.getFirst());

            // public Obejct getLast()

            // System.out.println("getLast:" + link.getLast());

            // public Object removeFirst()

            System.out.println("removeFirst:" + link.removeFirst());

            // public Object removeLast()

            System.out.println("removeLast:" + link.removeLast());

            // 输出对象名

            System.out.println("link:" + link);

        }

    }  

    ▶5set集合:存储的元素唯一,无序,方法和Collection一致。

     * Collection

     *         |--List

     *             有序(存储顺序和取出顺序一致),可重复

     *         |--Set

     *             无序(存储顺序和取出顺序不一致),唯一

     *

     * HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。

     * 注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,

     * 而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。

     */public class SetDemo {

        public static void main(String[] args) {

            // 创建集合对象

            Set<String> set = new HashSet<String>();

            // 创建并添加元素

            set.add("hello");

            set.add("java");

            set.add("world");

            set.add("java");

            set.add("world");

            // 增强for

            for (String s : set) {

                System.out.println(s);

            }

        }

    }

    ▶5.1、HashSet集合:哈希表结构,不同步,保证元素唯一性的方式依赖于:hashCode(),equals()方法。查询速度快。

    注意: 1、什么是哈希表呢?

    哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,算法这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

        2、保证元素唯一的原理

    当给哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

    总结:保证元素的唯一,其实就是根据对象的hashCodeequals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCodeequals方法建立属于当前对象的比较方式。

    HashSet:保证元素唯一的原理

     *        A:底层数据结构是哈希表(是一个元素为链表的数组)

     *        B:哈希表底层依赖两个方法:hashCode()和equals()

     

     * 步骤:

     *         首先比较哈希值

     *         如果相同,继续走,比较地址值或者走equals()

     *         如果不同,就直接添加到集合中    

     * 按照方法的步骤来说:    

     *         先看hashCode()值是否相同

     *             相同:继续走equals()方法

     *                 返回true:说明元素重复,就不添加

     *                 返回false:说明元素不重复,就添加到集合

     *             不同:就直接把元素添加到集合

     * 如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。

     * 而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。

     */public class HashSetDemo {

        public static void main(String[] args) {

            // 创建集合对象

            HashSet<String> hs = new HashSet<String>();

            // 创建并添加元素

            hs.add("hello");

            hs.add("world");

            hs.add("java");

            hs.add("world");

            // 遍历集合

            for (String s : hs) {

                System.out.println(s);

            }

        }

    }

    ▶5.2TreeSet集合:保证元素唯一,并能够对元素按照某种规则(自然排序和比较器排序)进行排序。

      注意: 1、如何保证元素唯一性的呢?

          使用的对象比较方法的结果是否为0,是0,视为相同元素不存。

         2、排序原理

         A:自然排序(元素具备比较性)
                            让元素所属的类实现自然排序接口 Comparable
         B:比较器排序(集合具备比较性)
             让集合的构造方法接收一个比较器接口的子类对象 Comparator

    自然排序:

    /*

     * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口

     */public class Student implements Comparable<Student> {

        private String name;

        private int age;

     

        public Student() {

            super();

        }

     

        public Student(String name, int age) {

            super();

            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 int compareTo(Student s) {

            // 主要条件 姓名的长度

            int num = this.name.length() - s.name.length();

            // 姓名的长度相同,不代表姓名的内容相同

            int num2 = num == 0 ? this.name.compareTo(s.name) : num;

            // 姓名的长度和内容相同,不代表年龄相同,所以还得继续判断年龄

            int num3 = num2 == 0 ? this.age - s.age : num2;

            return num3;

        }

    }

    /*

     * TreeSet:能够对元素按照某种规则进行排序。

     * 排序有两种方式

     * A:自然排序

     * B:比较器排序

     * TreeSet集合的特点:排序和唯一

     * 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。

     */public class TreeSetDemo {

        public static void main(String[] args) {

            // 创建集合对象

            // 自然顺序进行排序

            TreeSet<Integer> ts = new TreeSet<Integer>();

            // 创建元素并添加

            // 20,18,23,22,17,24,19,18,24

            ts.add(20);

            ts.add(18);

            ts.add(23);

            ts.add(22);

            ts.add(17);

            ts.add(24);

            ts.add(19);

            ts.add(18);

            ts.add(24);

            // 遍历

            for (Integer i : ts) {

                System.out.println(i);

            }

        }

    }

     比较器排序

    public class Student {

        private String name;

        private int age;

        public Student() {

            super();

        }

        public Student(String name, int age) {

            super();

            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;

        }

    }

    /*

     * 需求:请按照姓名的长度排序

     *

     * TreeSet集合保证元素排序和唯一性的原理

     * 唯一性:是根据比较的返回是否是0来决定。

     * 排序:

     *         A:自然排序(元素具备比较性)

     *            让元素所属的类实现自然排序接口 Comparable

     *         B:比较器排序(集合具备比较性)

     *            让集合的构造方法接收一个比较器接口的子类对象 Comparator

     */

    public class TreeSetDemo {

        public static void main(String[] args) {

            // 创建集合对象

            // TreeSet<Student> ts = new TreeSet<Student>(); //自然排序

            // public TreeSet(Comparator comparator) //比较器排序

            // TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());

     

            // 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象

            // 而匿名内部类就可以实现这个东西,匿名内部类和下面的MyComparator效果一样

            TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

                @Override

                public int compare(Student s1, Student s2) {

                    // 姓名长度

                    int num = s1.getName().length() - s2.getName().length();

                    // 姓名内容

                    int num2 = num == 0 ? s1.getName().compareTo(s2.getName())

                            : num;

                    // 年龄

                    int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;

                    return num3;

                }

            });

            // 创建元素

            Student s1 = new Student("linqingxia", 27);

            Student s2 = new Student("zhangguorong", 29);

            Student s3 = new Student("wanglihong", 23);

            Student s4 = new Student("linqingxia", 27);

            Student s5 = new Student("liushishi", 22);

            Student s6 = new Student("wuqilong", 40);

            Student s7 = new Student("fengqingy", 22);

            Student s8 = new Student("linqingxia", 29);

     

            // 添加元素        ts.add(s1);

            ts.add(s2);

            ts.add(s3);

            ts.add(s4);

            ts.add(s5);

            ts.add(s6);

            ts.add(s7);

            ts.add(s8);

     

            // 遍历

            for (Student s : ts) {

                System.out.println(s.getName() + "---" + s.getAge());

            }

        }

    }

    //或者去掉匿名内部类。增加一个MyComparator类

    public class MyComparator implements Comparator<Student> {

     @Override
     public int compare(Student s1, Student s2) {
      // int num = this.name.length() - s.name.length();
      // this -- s1
      // s -- s2
      // 姓名长度
      int num = s1.getName().length() - s2.getName().length();
      // 姓名内容
      int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
      // 年龄
      int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
      return num3;
     }

    }

    ▶5.3、LinkedHashSet:HashSet的一个子类,底层数据结构由哈希表和链表组成保证元素的唯一和有序。
      哈希表保证元素的唯一性。
      链表保证元素有序。(存储和取出是一致)

    /*

     * LinkedHashSet:底层数据结构由哈希表和链表组成。

     * 哈希表保证元素的唯一性。

     * 链表保证元素有序。(存储和取出是一致)

     */public class LinkedHashSetDemo {

        public static void main(String[] args) {

            // 创建集合对象

            LinkedHashSet<String> hs = new LinkedHashSet<String>();

            // 创建并添加元素

            hs.add("hello");

            hs.add("world");

            hs.add("java");

            hs.add("world");

            hs.add("java");

     

            // 遍历

            for (String s : hs) {

                System.out.println(s);

            }

        }

    }

    6集合总结

      Collection
          |--List 有序,可重复
               |--ArrayList
                  底层数据结构是数组,查询快,增删慢。
                  线程不安全,效率高
               |--Vector
                  底层数据结构是数组,查询快,增删慢。
                  线程安全,效率低
               |--LinkedList
                  底层数据结构是链表,查询慢,增删快。
                  线程不安全,效率高
          |--Set 无序,唯一
               |--HashSet
                  底层数据结构是哈希表。
                  如何保证元素唯一性的呢?
                     依赖两个方法:hashCode()equals()
                     开发中自动生成这两个方法即可
                  |--LinkedHashSet
                     底层数据结构是链表和哈希表
                     由链表保证元素有序
                     由哈希表保证元素唯一
               |--TreeSet
                  底层数据结构是红黑树。
                  如何保证元素排序的呢?
                     自然排序
                     比较器排序
                如何保证元素唯一性的呢?
                   根据比较的返回值是否是0来决定

    7、针对Collection集合我们到底使用谁呢
      唯一吗?
           是:Set
          排序吗?
             是:TreeSet
             否:HashSet
        如果你知道是Set,但是不知道是哪个Set,就用HashSet
        否:List
           要安全吗?
             是:Vector
             否:ArrayList或者LinkedList
                 查询多:ArrayList
                 增删多:LinkedList
       如果你知道是List,但是不知道是哪个List,就用ArrayList
       如果你知道是Collection集合,但是不知道使用谁,就用ArrayList
       如果你知道用集合,就用ArrayList
    8、在集合中常见的数据结构
       ArrayXxx:底层数据结构是数组,查询快,增删慢
       LinkedXxx:底层数据结构是链表,查询慢,增删快
       HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()equals()
       TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

    java学习笔记 --- 集合(续) 

    1map集合

      1.1、特点:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

      1.2Map集合和Collection集合的区别?
         Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。可以把这个理解为:夫妻对
         Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的。可以把这个理解为:光棍(11.11)

      1.3Map集合的功能概述:
        1:添加功能
          V put(K key,V value):添加元素。
        如果键是第一次存储,就直接存储元素,返回null
         如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
          2:删除功能
             void clear():移除所有的键值对元素
             V remove(Object key):根据键删除键值对元素,并把值返回
          3:判断功能
           boolean containsKey(Object key):判断集合是否包含指定的键
           boolean containsValue(Object value):判断集合是否包含指定的值
            boolean isEmpty():判断集合是否为空
          4:获取功能
            Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
            V get(Object key):根据键获取值
            Set<K> keySet():获取集合中所有键的集合
            Collection<V> values():获取集合中所有值的集合
          5:长度功能
           int size():返回集合中的键值对的对数  

    public class MapDemo {

        public static void main(String[] args) {

            // 创建集合对象

            Map<String, String> map = new HashMap<String, String>();

     

            // 添加元素

            // V put(K key,V value):添加元素。这个其实还有另一个功能?先不告诉你,等会讲

            // System.out.println("put:" + map.put("文章", "马伊俐"));

            // System.out.println("put:" + map.put("文章", "姚笛"));

            map.put("邓超", "孙俪");

            map.put("黄晓明", "杨颖");

            map.put("周杰伦", "蔡依林");

            map.put("刘恺威", "杨幂");

     

            // void clear():移除所有的键值对元素

            // map.clear();

     

            // V remove(Object key):根据键删除键值对元素,并把值返回

            // System.out.println("remove:" + map.remove("黄晓明"));

            // System.out.println("remove:" + map.remove("黄晓波"));

     

            // boolean containsKey(Object key):判断集合是否包含指定的键

            // System.out.println("containsKey:" + map.containsKey("黄晓明"));

            // System.out.println("containsKey:" + map.containsKey("黄晓波"));

     

            // boolean isEmpty():判断集合是否为空

            // System.out.println("isEmpty:"+map.isEmpty());

            

            //int size():返回集合中的键值对的对数

            System.out.println("size:"+map.size());

     

            // 输出集合名称

            System.out.println("map:" + map);

        }

    }

    /*

     * 获取功能:

     * V get(Object key):根据键获取值

     * Set<K> keySet():获取集合中所有键的集合

     * Collection<V> values():获取集合中所有值的集合

     */public class MapDemo2 {

        public static void main(String[] args) {

            // 创建集合对象

            Map<String, String> map = new HashMap<String, String>();

     

            // 创建元素并添加元素

            map.put("邓超", "孙俪");

            map.put("黄晓明", "杨颖");

            map.put("周杰伦", "蔡依林");

            map.put("刘恺威", "杨幂");

     

            // V get(Object key):根据键获取值

            System.out.println("get:" + map.get("周杰伦"));

            System.out.println("get:" + map.get("周杰")); // 返回null

            System.out.println("----------------------");

     

            // Set<K> keySet():获取集合中所有键的集合

            Set<String> set = map.keySet();

            for (String key : set) {

                System.out.println(key);

            }

            System.out.println("----------------------");

     

            // Collection<V> values():获取集合中所有值的集合

            Collection<String> con = map.values();

            for (String value : con) {

                System.out.println(value);

            }

        }

    }

    /**map集合的遍历:2 种方式*//*

     * Map集合的第一种遍历。

     * Map -- 夫妻对

     * 思路:

     *         A:把所有的丈夫给集中起来。

     *         B:遍历丈夫的集合,获取得到每一个丈夫。

     *         C:让丈夫去找自己的妻子。

     *

     * 转换:

     *         A:获取所有的键

     *         B:遍历键的集合,获取得到每一个键

     *         C:根据键去找值

     */public class MapDemo3 {

        public static void main(String[] args) {

            // 创建集合对象

            Map<String, String> map = new HashMap<String, String>();

     

            // 创建元素并添加到集合

            map.put("杨过", "小龙女");

            map.put("郭靖", "黄蓉");

            map.put("杨康", "穆念慈");

            map.put("陈玄风", "梅超风");

     

            // 遍历

            // 获取所有的键

            Set<String> set = map.keySet();

            // 遍历键的集合,获取得到每一个键

            for (String key : set) {

                // 根据键去找值

                String value = map.get(key);

                System.out.println(key + "---" + value);

            }

        }

    }

    /*

     * Map集合的第2种遍历。

     * Map -- 夫妻对

     *

     * 思路:

     *         A:获取所有结婚证的集合

     *         B:遍历结婚证的集合,得到每一个结婚证

     *         C:根据结婚证获取丈夫和妻子

     *

     * 转换:

     *         A:获取所有键值对对象的集合

     *         B:遍历键值对对象的集合,得到每一个键值对对象

     *         C:根据键值对对象获取键和值

     *

     * 这里面最麻烦的就是键值对对象如何表示呢?

     *

     *         Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合

     */public class MapDemo4 {

        public static void main(String[] args) {

            // 创建集合对象

            Map<String, String> map = new HashMap<String, String>();

     

            // 创建元素并添加到集合

            map.put("杨过", "小龙女");

            map.put("郭靖", "黄蓉");

            map.put("杨康", "穆念慈");

            map.put("陈玄风", "梅超风");

     

            // 获取所有键值对对象的集合

            Set<Map.Entry<String, String>> set = map.entrySet();

            // 遍历键值对对象的集合,得到每一个键值对对象

            for (Map.Entry<String, String> me : set) {

                // 根据键值对对象获取键和值

                String key = me.getKey();

                String value = me.getValue();

                System.out.println(key + "---" + value);

            }

        }

    }

    2HashMap:Map集合的子类。是基于哈希表的Map接口实现。
               哈希表的作用是用来保证键的唯一性的。

    public class HashMapDemo2 {

        public static void main(String[] args) {

            // 创建集合对象

            HashMap<Integer, String> hm = new HashMap<Integer, String>();

     

            // 创建元素并添加元素

            // Integer i = new Integer(27);

            // Integer i = 27;

            // String s = "林青霞";

            // hm.put(i, s);

            hm.put(27, "林青霞");

            hm.put(30, "风清扬");

            hm.put(28, "刘意");

            hm.put(29, "林青霞");

     

            // 下面的写法是八进制,但是不能出现8以上的单个数据

            // hm.put(003, "hello");

            // hm.put(006, "hello");

            // hm.put(007, "hello");

            // hm.put(008, "hello");

     

            // 遍历

            Set<Integer> set = hm.keySet();

            for (Integer key : set) {

                String value = hm.get(key);

                System.out.println(key + "---" + value);

            }

     

            // 下面这种方式仅仅是集合的元素的字符串表示

            // System.out.println("hm:" + hm);    }

    }

     3 LinkedHashMap:HashMap的子类,是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。
          由哈希表保证键的唯一性
          由链表保证键盘的有序(存储和取出的顺序一致)

    /*

     * LinkedHashMap:是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。

     * 由哈希表保证键的唯一性

     * 由链表保证键盘的有序(存储和取出的顺序一致)

     */public class LinkedHashMapDemo {

        public static void main(String[] args) {

            // 创建集合对象

            LinkedHashMap<String, String> hm = new LinkedHashMap<String, String>();

     

            // 创建并添加元素

            hm.put("2345", "hello");

            hm.put("1234", "world");

            hm.put("3456", "java");

            hm.put("1234", "javaee");

            hm.put("3456", "android");

     

            // 遍历

            Set<String> set = hm.keySet();

            for (String key : set) {

                String value = hm.get(key);

                System.out.println(key + "---" + value);

            }

        }

    }

    4TreeMap:是基于红黑树的Map接口的实现。

    /*

     * TreeMap:是基于红黑树的Map接口的实现。

     *

     * HashMap<String,String>

     * 键:String

     * 值:String

     */public class TreeMapDemo {

        public static void main(String[] args) {

            // 创建集合对象

            TreeMap<String, String> tm = new TreeMap<String, String>();

     

            // 创建元素并添加元素

            tm.put("hello", "你好");

            tm.put("world", "世界");

            tm.put("java", "爪哇");

            tm.put("world", "世界2");

            tm.put("javaee", "爪哇EE");

     

            // 遍历集合

            Set<String> set = tm.keySet();

            for (String key : set) {

                String value = tm.get(key);

                System.out.println(key + "---" + value);

            }

        }

    }

    5Collections:是针对集合进行操作的工具类,都是静态方法。

      1CollectionCollections的区别?
        Collection:是单列集合的顶层接口,有子接口ListSet
        Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法

      2Collections方法:

        public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。
        public static <T> int binarySearch(List<?> list,T key):二分查找
        public static <T> T max(Collection<?> coll):最大值
        public static void reverse(List<?> list):反转
        public static void shuffle(List<?> list):随机置换

    public class CollectionsDemo {

        public static void main(String[] args) {

            // 创建集合对象

            List<Integer> list = new ArrayList<Integer>();

     

            // 添加元素

            list.add(30);

            list.add(20);

            list.add(50);

            list.add(10);

            list.add(40);

     

            System.out.println("list:" + list);

            // public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。

            // Collections.sort(list);

            // System.out.println("list:" + list);

            // [10, 20, 30, 40, 50]

            // public static <T> int binarySearch(List<?> list,T key):二分查找

            // System.out

            // .println("binarySearch:" + Collections.binarySearch(list, 30));

            // System.out.println("binarySearch:"

            // + Collections.binarySearch(list, 300));

            // public static <T> T max(Collection<?> coll):最大值

            // System.out.println("max:"+Collections.max(list));

     

            // public static void reverse(List<?> list):反转

            // Collections.reverse(list);

            // System.out.println("list:" + list);

            

            //public static void shuffle(List<?> list):随机置换        Collections.shuffle(list);

            System.out.println("list:" + list);

        }

    }

  • 相关阅读:
    北漂IT男返乡2年的三线楼市观察(宜昌夷陵篇)-原创
    写一本书作者到底能拿到多少稿酬?
    书是如何定价的?
    一本书出版社拿多少,作者拿多少?书的成本几何?出版一本书出版社到底能赚多少钱?(转)
    微服务架构最强详解
    今日头条号短视频自媒体研究---最开始的短视频设备资金投入不要太大(原创)
    今日头条号短视频自媒体研究---新手上路,正确拍短视频并上传(原创)
    HTTP请求中的缓存(cache)机制
    linux kernel 中断子系统之(一)-- ARM GIC 硬件【转】
    嵌入式Linux——kmsg:分析/proc/kmsg文件以及写自己的/proc/mymsg【转】
  • 原文地址:https://www.cnblogs.com/Steven5007/p/6637764.html
Copyright © 2020-2023  润新知