Java集合框架图

2012053020261738.jpg

List

  • List中的数据有顺序,可以重复

  • ArrayList:底层实现是数组,线程不安全,效率高,查询,修改效率高,插入,删除效率低

  • LinkedList:底层实现是链表,线程不安全,效率高,查询,修改效率低,插入,删除效率高

  • Vector:线程安全,效率低

  • LinkedList在查找的时候会对要查找的位置与size/2比较,大于则从后向前找,否则从前向后找,提高了效率

Map

  • Map采用键值对的形式存储数据,如果键重复则覆盖之前的值

  • Map底层采用数组+链表的数据结构,相同HashCode的元素存储在数组的同一位置的链表上,如果元素equals则覆盖,否则添加到链表上

  • 如果两个元素equals则HashCode一定相同,HashCode相同不一定equals

  • 如果要比较Map中的元素,一定要重写该元素的HashCode方法和equals方法,默认的equals为==

Set

  • HashSet的底层为HashMap,Set的不可重复就是利用了map里面键对象的不可重复

  • Set中的数据没有顺序,不可以重复

  • Set接口的实现类常用的有HashSet,特点是:没有是顺序,不可以重复,重复的元素添加进行会出现覆盖的现象

Iterator

  • 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象

  • Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作

  • Iterator接口定义了如下方法:

    • boolean hasNext(); //判断是否有元素没被遍历

    • Object next(); //返回游标当前位置的元素并将游标移动到下一位置

    • void remove(); //删除游标左面的元素,在执行完next之后该操作只能执行一次

QQ截图20161008135623.png

  • 增强for必须实现java.lang.Iterable接口,重写iterator方法

Comparable接口

  • 排序的实体类都实现了java.lang.Comparable接口,Comparable接口中只有一个方法

    public int compareTo(Object obj)

    该方法:

    返回 0 表示 this == obj

    返回正数 表示 this > obj

    返回负数 表示 this < obj

  • 实现了Comparable接口的类通过实现compareTo方法从而确定该类对象的排序方式

  • 内置类

    • 整数,小数, Integer Float Double 直接比较基本数据类型的大小

    • 字符:比较Unicode码之差

    • 字符串:

      • 如果其中一个是另外一个起始开始的字串,返回长度之差

      • 否则返回第一个不相等的Unicode码之差

    • java.util.data:根据日期的长整数比较

用冒泡排序对String排序:

public class innerObjectSort {

    public static void main(String[] args) {

        String[] arr ={"a","abcd","abc","def"};
        boolean sorted = true;  
        int len = arr.length; //假定有序
        for(int i=0;i<len-1;i++){
            sorted = true;
            for(int j=0;j<len-i-1;j++){
                String t;
                if(((Comparable)arr[j]).compareTo(arr[j+1])>0){
                    t = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = t;
                    sorted = false;
                }
            }
            if (sorted) {
                break;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

数组排序(使用泛型)

/**
     * 数组排序(使用泛型)
     */
    public static <T extends Comparable<T>> void sort(T[] arr) {

        boolean sorted = true;  
        int len = arr.length; //假定有序
        for(int i=0;i<len-1;i++){
            sorted = true;
            for(int j=0;j<len-i-1;j++){
                T t;
                if(((Comparable)arr[j]).compareTo(arr[j+1])>0){
                    t = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = t;
                    sorted = false;
                }
            }
            if (sorted) {
                break;
            }
        }
    }

Comparator

  • 提供排序的比较器,业务比较器

    • 实现java.util.Comparator接口

    • 重写public int compare(T o1,T o2);

  • 作用

    • 解耦:独立于实体类

    • 方便:便于应对各种排序规则

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class StringComp implements Comparator<String>{

   //按长度比较大小

    @Override
    public int compare(String o1, String o2) {
        int len1 = o1.length();
        int len2 = o2.length();
        return len1-len2;
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("abcd");
        list.add("abc");
        list.add("def");
        StringComp comp = new StringComp();
        Collections.sort(list,comp);
        System.out.println(list);
    }

}

排序容器TreeSet与TreeMap

  • TreeMap:确保key可以排序或者提供比较器

    public TreeMap(Comparator<? super K> comparator)

  • TreeSet:确保元素实体可以排序或者提供比较器

    public TreeSet(Comparator<? super E> comparator)

  • 元素必须重写hashcode和equals方法

Demo

public class Person {

    private String name;
    private int handsom;

    public Person() {
    }

    public Person(String name, int handsom) {
        super();
        this.name = name;
        this.handsom = handsom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHandsom() {
        return handsom;
    }

    public void setHandsom(int handsom) {
        this.handsom = handsom;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "姓名:"+name+",帅气指数:"+handsom+"\n";
    }
}
import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {

    public static void main(String[] args) {

        Person p1 = new Person("你",100);
        Person p2 = new Person("刘德华",1000);
        Person p3 = new Person("梁朝伟",1200);
        Person p4 = new Person("张三",50);

        TreeSet<Person> persons = new TreeSet<Person>(
                new Comparator<Person>() {

                    @Override
                    public int compare(Person p1, Person p2) {
                        return p1.getHandsom() - p2.getHandsom();
                    }

                }
           );

        persons.add(p1);
        //Treeset在添加数据时排序,不要修改数据,否则可能重复,可以加final
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);

        System.out.println(persons);

    }

}

Collections工具类常见方法的使用

  • binarySearch(List<? extends Comparable<? super T>> list, T key) 二分查找,要求容器有序

  • sort(List list) 排序

    sort(List list, Comparator<? super T> c)

  • reverse(List<?> list) 反转

  • shuffle(List<?> list) 打乱顺序,洗牌

  • swap(List<?> list, int i, int j) 交换

public static void main(String[] args) {
        List<Integer> cards =new ArrayList<Integer>();
        //shuffle 洗牌 模拟斗地主
        for(int i=0;i<54;i++){
            cards.add(i); 
        }
        //洗牌
        Collections.shuffle(cards) ;
        //依次发牌
        List<Integer> p1 =new ArrayList<Integer>();
        List<Integer> p2 =new ArrayList<Integer>();     
        List<Integer> p3 =new ArrayList<Integer>();
        List<Integer> last =new ArrayList<Integer>();
        for(int i=0;i<51;i+=3){
            p1.add(cards.get(i));
            p2.add(cards.get(i+1));
            p3.add(cards.get(i+2));
        }
        //最后三张为底牌
        last.add(cards.get(51));
        last.add(cards.get(52));
        last.add(cards.get(53));

        System.out.println("第一个人:"+p1);
        System.out.println("第二个人:"+p2);
        System.out.println("第三个人:"+p3);
        System.out.println("底牌为:"+last);

    }
    //反转
    public static void test1(){
        List<Integer> list =new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println(list);
        Collections.reverse(list);
        System.out.println("反转之后"+list);
    }