java 集合Collection

1. java集合框架图

图片来源  https://blog.csdn.net/u010887744/article/details/50575735

 

2. 迭代器

Iterator:迭代器,它是Java集合的顶层接口(不包括 map 系列的集合,Map接口 是 map 系列集合的顶层接口)

使用场景:只要实现了Iterable接口的类,就可以使用Iterator迭代器,注意:map系列集合不能够使用迭代器

迭代器函数:

Object next():返回迭代器刚越过的元素的引用,返回值是 Object,

Iterator<Student> it = arr.iterator();  // 这样使用时可以不强制类型转换

boolean hasNext():判断容器内是否还有可供访问的元素

void remove():删除迭代器刚越过的元素

 

3. 集合遍历的三种方法:

    public static void main(String[] args) {
        ArrayList<Student> arr = new ArrayList<Student>();
        Student s1 = new Student("linqinxia", 216);
        Student s2 = new Student("diaochan", 78);
        Student s3 = new Student("wnagjing", 78);
        Student s4 = new Student("wnagjun", 88);

        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        arr.add(s4);
        // 方法1:迭代器遍历
        Iterator<Student> it = arr.iterator();
        while (it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
        // 方法2:增强for 遍历
        for (Student m : arr) {
            System.out.println(m.getName() + "----" + m.getAge());
        }
        // 方法3:使用for 循环遍历
        for (int x = 0; x < arr.size(); x++) {
            Student s = (Student) arr.get(x);
            System.out.println(s.getName() + "----" + s.getAge());
        }
    }

 

4. collection(接口,继承自Iterable,实现:AbstractCollection):

    public static void main(String[] args) {
        Collection<Person> c1 = new ArrayList<Person>();
        Collection<Student> c2 = new ArrayList<Student>();
        Collection<Student> c3 = new ArrayList<Student>();
        Person p1 = new Person();
        Person p2 = new Person();
        Person p3 = new Person();
        Student s1 = new Student("wangjing", 20);
        Student s2 = new Student("wangjun", 21);
        Student s3 = new Student("xiaoha", 19);
        Student s4 = new Student("wangjing", 20);
        c1.add(p1);                //1. add(#):添加一个元素                    
        c1.add(p2);
        c1.add(p3);
        c2.add(s1);
        c2.add(s2);
        c2.add(s3);
        c3.add(s4);
        c1.addAll(c2);            //2. addAll(Collection<? extends E>):添加另一个集合中所有的元素
        System.out.println(c1.size());
        c1.clear();                //3. clear():清除集合中所有的元素
        System.out.println(c1.size());
        System.out.println(c2.contains(s2));    //4. contains(Object):判断该元素是否在集合中
        System.out.println(c2.containsAll(c3));    //5. containsAll(Collection<? extends E>):判断输入集合所有元素是否在该集合中
        c3.add(s2);
        c3.add(s3);
        System.out.println(c2.equals(c3));        //6. equals(Object):判断两个集合中所有的元素是否相等,只需要判断c2中的每一个元素是否equals c3中的一个元素,equals可以重写
        System.out.println(c2.hashCode());        //7. hashCode():返回集合的hashCode编码
        Iterator<Student> it = c2.iterator();    //8. iterator():返回集合的迭代器
        while(it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName() + ":" + s.getAge());
        }
        System.out.println(c2.parallelStream());    //9. parallelStream():返回java.util.stream.ReferencePipeline$Head@5c647e05
        c2.remove(s2);                            //10. remove(Object):删除一个元素
        System.out.println(c2.size());
        c2.add(s2);
        c2.removeAll(c3);                    // 11. removeAll(Collection<?>) 
        System.out.println(c2.size());
        c2.size();                            //12. c2.size():返回集合的大小
        c2.add(s1);
        c2.add(s2);
        c2.add(s3);
        Student[] s = c2.toArray(new Student[0]);    //13 toArray[T[]] 将集合转换成数组    数组转集合的方法:List<String> mlist = Arrays.asList(array);
        System.out.println(s[1].getName());
        Object[] objs = c2.toArray();                //14 toArray[],集合转数组
        System.out.println(Arrays.toString(objs));
        c3.clear();
        c3.add(s1);
        c3.add(s2);
        c2.retainAll(c3);            //15 retainAll(): c2中的元素全部使用c3中的元素代替
        Object[] obj = c2.toArray();                
        System.out.println(Arrays.toString(obj));
    }

 

5 List(接口,继承自Collection,实现:AbstractCollection,有序(存储顺序与取出顺序一致)可以重复)

    public static void main(String[] args) {
        List<String> s = new ArrayList<String>();
        s.add("wangjing");
        s.add("wangjun");
        s.add("wangjing");
        s.add("xiaoha");
        s.add("wangjing");
        System.out.println(s.indexOf("wangjing")); // indexOf(Object) 返回对象在集合中首次出现的索引
        System.out.println(s.lastIndexOf("wangjing")); // lastIndexOf(Object) 返回对象在集合中最后一次出现的索引
        ListIterator<String> lt = s.listIterator(); // listIterator 返回ListIterator接口的具体实现
        // ------------------------ListIterator---------------------------------
        System.out.println(lt.next()); // ListIterator:next() 返回下一个对象,注意,next()第一次使用后对应的索引是0
        System.out.println(lt.previous()); // ListIterator:previous() 返回上一个对象
        lt.next();
        lt.next();
        System.out.println(lt.nextIndex()); // ListIterator:nextIndex() 返回下一个next()对象的索引
        lt.add("lainglaing"); // ListIterator:add(E) 从当前索引所在的位置插入对象,next()指向第几个对象,从第几个对象的位置插入
        while (lt.hasNext()) { // ListIterator:Next() 判断是否有前一个对象
            lt.next();
        }
        while (lt.hasPrevious()) { // ListIterator:hasPrevious() 判断是否有前一个对象
            System.out.println(lt.previous());
        }
        System.out.println("--------");
        lt.remove(); // ListIterator:remove() 删除迭代器最后一次操作的元素,此次删除的是集合的第一个元素
        while (lt.hasNext()) { // ListIterator:Next() 判断是否有前一个对象
            System.out.println(lt.next());
        }
        lt.set("xiaohuang"); // ListIterator:set(E) 将迭代器最后一次返回的对象用E替代
        while (lt.hasPrevious()) { // ListIterator:hasPrevious() 判断是否有前一个对象
            lt.previous();
        }
        while (lt.hasNext()) { // ListIterator:Next() 判断是否有前一个对象
            System.out.println(lt.next());
        }
        System.out.println("*************************88");
        // ------------------------------------------------------------------------
        ListIterator<String> lm = s.listIterator(3); // listIterator(n) 取集合前n-1个元素转换成ListIterator
        while (lm.hasNext()) { // ListIterator:Next() 判断是否有前一个对象
            System.out.println(lm.next());
        }

        List<String> li = s.subList(0, 3);            //sublist(int, int) 截断操作,包左不包右
        for (int i = 0; i < li.size(); i++) {
            System.out.println(li.get(i));
        }
        System.out.println("--------------");
        s.set(1, "wangwangwang");                //set(int, E):修改第n个对象,使用E代替
        for (int i = 0; i < s.size(); i++) {
            System.out.println(s.get(i));
        }
    }

5.1 ArrayList

特点:底层数据结构是数组,查询快,增删慢

线程不安全,效率高

5.2 Vector

特点:底层数据结构是数组,查询快,增删慢

线程安全,效率低

5.3 LinkedList

特点:底层数据结构是链表,查询慢,增删快

线程不安全,效率高

6. Set(元素唯一性)

 6.1 HashSet

特点:基于哈希表:一个元素为链表的数组,综合了数组和链表的特点,无序

重要:唯一性依赖于底层的hashCode()和equals()

public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        set.add("hello");        //add(E): 底层依赖hashCode() 和 equals()
        set.add("java");        //String重写了hashCode() 和 equals()
        set.add("world");
        set.add("hello");
        set.add("java");
        set.add("world");
        for(String s:set) {
            System.out.println(s);        //java world hello
        }
        Set<Student> hs = new HashSet<Student>();
        Student s1 = new Student("wangjing", 20);
        Student s2 = new Student("wangjun", 20);
        Student s3 = new Student("wangjing", 20);
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        System.out.println(hs);
    }

6.2 HashSet的子类LinkedHashSet

特点:具有可预知的迭代顺序的set接口的哈希表(唯一性)和链表(有序)实现

public static void main(String[] args) {
        LinkedHashSet<String> hs = new LinkedHashSet<String>();
        hs.add("hello");
        hs.add("world");
        hs.add("java");
        hs.add("world");
        System.out.println(hs);    // [hello, world, java]
    }

6.3 TreeSet(继承自AbstractSet)

特点:能够对元素按照某种规则排序

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

排序的两种方法:

A:自然排序

自然排序重要:真正的比较依赖于元素的compareTo()方法,这个方法是定义在Comparable里面的,如果想重写该方法,必须实现Comparable接口

TreeSet的底层是二叉树结构(红黑树:自平衡的二叉树,二叉检索树,对于二叉检索树的任意一个节点,设其值为K,则该节点左子树中的任意一个节点的值都小于K,该节点右子树中的任意一个节点的值都大于等于K,如果按照中序遍历将各个节点打印出来,就会得到从小到大排列的节点。)

compareTo方法写法:

学生类按照年龄排序:

@Override
    public int compareTo(Student o) {
        int num = this.age - o.age;
        int nu = num == 0 ? this.name.compareTo(o.name) : num;
        return nu;
        // 返回0,则不添加,返回数大于0,添加到二叉树右边,返回数小于0,添加到二叉树左边,实现了去重
    }

学生类按照姓名的长度排序

@Override
    public int compareTo(Student o) {
        int num = this.name.length();
        int nu = num == 0 ? this.name.compareTo(o.name) : num;
        int numu = nu == 0 ? this.age - o.age : nu;
        return numu;
        // 返回0,则不添加,返回数大于0,添加到右边,返回数小于0,添加到左边
    }

B:比较器排序

public TreeSet(Comparator<? super E> comparator)

第一种方法:使用外部类,比较麻烦

public class MyComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        // TODO Auto-generated method stub
        int num1 = o1.getName().length() - o2.getName().length();
        int num2 = num1 == 0 ? o1.getName().compareTo(o2.getName()) : num1;
        int num3 = num2 == 0 ? o1.getAge() - o2.getAge() : num2;
        return num3;
    }
    
}


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

第二种方法:匿名内部类实现(常用)

TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // TODO Auto-generated method stub
                int num1 = o1.getName().length() - o2.getName().length();
                int num2 = num1 == 0 ? o1.getName().compareTo(o2.getName()) : num1;
                int num3 = num2 == 0 ? o1.getAge() - o2.getAge() : num2;
                return num3;
            }
        });

 7. Collections:工具类

collection与collections的区别:

1. collection:是单列集合的顶层接口,有子接口List和Set

2. Collection:是针对集合操作的工具类,有对集合进行排序和二分查找的方法

public static <T> void sort(List<T> list):排序,默认自然排序

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

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

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

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

public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(30);
        list.add(29);
        list.add(50);
        list.add(80);
        Collections.sort(list);
        System.out.println("list:" + list);
        System.out.println("binarySearch:" + Collections.binarySearch(list, 300));
        System.out.println("max:" + Collections.max(list));
        Collections.reverse(list);
        System.out.println("list:" + list);
        Collections.shuffle(list);        // 随机置换
        System.out.println("list:" + list);
    }
    public static void main(String[] args) {
        List<Student> list = new ArrayList<Student>();
        
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("风清扬", 30);
        Student s3 = new Student("留意", 30);
        Student s4 = new Student("武松", 399);
        Student s5 = new Student("武松", 399);
        
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        list.add(s5);
        
        Collections.sort(list);        // 相同的元素不可以去除
        System.out.println("list:" + list);
        Collections.sort(list, new Comparator<Student>(){

            @Override
            public int compare(Student o1, Student o2) {
                int num = o1.getAge() - o2.getAge();
                int num2 = num==0 ? o1.getName().compareTo(o2.getName()) : num;
                return num2;
            }
            
        });
    }

 

posted @ 2018-08-03 21:47  风影旋新月  阅读(139)  评论(0编辑  收藏  举报