Java集合

目录

一、集合概述

1.1、集合和数组的区别

1.2、主要集合概述

1.2.1、List

1.2.2、Set 

1.2.3、Map

1.3、Collection和Iterator

1.3.1、Collection

1.3.2、Iterator

二、List接口

2.1、List接口概述

2.2、ArrayList代码示例

2.3、LinkedList代码示例

三、Set接口

3.1、哈希表

3.2、HashSet

3.3、代码示例

3.4、equals和hashCode

3.5、TreeSet概述

3.6、代码示例

3.7、实现Comparable接口完成程序

 3.8、实现Comparator接口完成排序

 3.9、Comparable 和 Comparator 的区别?

3.9.1、Comparable

3.9.2、Comparator

3.9.3、总结

四、Map接口

4.1、Map概述

4.2、HashMap

 4.3、HashMap采用自定义类作为Key

4.4、HashMap覆盖equals和hashCode方法

4.5、TreeMap 

五、Collections工具类


一、集合概述

1.1、集合和数组的区别

(1)数组声明了它容纳的元素的类型,而集合不声明。

(2)数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。

(3)数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)。

(4)数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。

1.2、主要集合概述

1.2.1、List

        List是一个有序的集合,可以放重复的元素。

1.2.2、Set 

        Set是一个无序的集合,不允许放重复的数据。

1.2.3、Map

        Map是一个无序集合,集合中包含一个键对象,一个值对象,键对象不允许重复,值对象可以重复。(身份证号 - 姓名)

1.3、Collection和Iterator

1.3.1、Collection

        Collection是List和Set的父接口,在Collection中定义了一些只要方法。

1.3.2、Iterator

        Iterator为迭代接口,通过此接口可以遍历集合中的数据。

二、List接口

2.1、List接口概述

List接口下面主要有两个实现ArrayList和LinkedList,他们都是有顺序的,也就是放进去是什么顺序,取出来还是什么顺序,也就是基于线性存储,可以看做是一个可变数组。

(1)ArrayList:查询数据比较快,添加和删除数据比较慢(基于可变数组)

(2)LinkedList:查询数据比较慢,添加和删除数据比较快(基于链表数据结构)

(3)Vector:Vector已经不建议使用,Vector中的方法都是同步的,效率慢,已经被ArrayList取代

(4)Stack:是继承Vector实现了一个栈,栈结构是先进后出,目前已被LinkedList取代

2.2、ArrayList代码示例

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        //最好不要这样写,这样属于面向具体编程了
        //无法达到灵活互换
        //最好面向接口编程
        ArrayList arrayList = new ArrayList();

        //采用面向接口编程
        //使用 Collection 会更灵活,如果 List 不能满足要求
        //那么可以采用 HashSet,因为 HashSet 也实现了该接口
        Collection c = new ArrayList();

        //面向接口编程
        //采用 list 接口可以使用 Collection 里的方法
        //也可以使用 list 接口扩展的方法
        List l = new ArrayList();
        //自动装箱,适合于 jdk1.5
        l.add(1);
        l.add(3);

        //jdk1.5 以前,必须如下使用
        l.add(new Integer(2));
        l.add(new Integer(4));

        //可以加入重复数据
        l.add(2);
        //不能加入字符串
        //在强制转换时会出现 ClassCastException 错误
        //l.add("sadfdsfs");
        //可以采用 List 接口的中 get()方法依次取得元素
        //输出结果为,不会打乱顺序
        /*
        13242
        */
        for (int i = 0; i < l.size(); i++) {
            //将 Object 强制转换为 Integer
            Integer e = (Integer) l.get(i);
            System.out.print(e + " ");
        }
        System.out.println("");
        //调用 remove 删除集合中的元素
        //如果元素重复会 remove 掉第一个匹配的
        l.remove(2);

        //采用 Iterator 遍历数据(while 循环)
        //Iterator 是一种模式,主要可以统一数据结构的访问方式
        //这样在程序中就不用关心各个数据结构的实现了
        //使对不同数据结构的遍历更加简单了,更加统一了
        Iterator iter = l.iterator();
        while (iter.hasNext()) {
            Integer v = (Integer) iter.next();
            System.out.print(v + " ");
        }
        System.out.println("");

        //采用 Iterator 遍历数据(for 循环)
        for (Iterator iter1 = l.iterator(); iter1.hasNext(); ) {
            Integer v = (Integer) iter1.next();
            System.out.print(v + " ");
        }
        System.out.println();

        //在集合中是否包含 3,输出为:true
        System.out.println(l.contains(3));
        //集合是否为空,输出:false
        System.out.println(l.isEmpty());
        System.out.println("");

        //转换成对象数组
        //这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArray[T[] a]方法导出的是指定类型的数组。
        Object[] oArray1 = l.toArray();
        for (int i = 0; i < oArray1.length; i++) {
            Integer v = (Integer) oArray1[i];
            System.out.print(v + " ");
        }
        System.out.println("");

        //运行时自动创建相应类型的数组
        Integer[] iArray = new Integer[l.size()];
        l.toArray(iArray);
        for (int i = 0; i < iArray.length; i++) {
            int v = iArray[i];
            System.out.print(v + " ");
        }
    }

}

output:

  

2.3、LinkedList代码示例

import java.util.*;

public class Test {
    public static void main(String[] args) {
        //最好不要这样写,这样属于面向具体编程了
        //无法达到灵活互换
        //最好面向接口编程
        LinkedList arrayList = new LinkedList();
        //采用面向接口编程
        Collection c = new LinkedList();
        //面向接口编程
        //采用 list 接口可以使用 Collection 里的方法
        //也可以使用 list 接口扩展的方法
        //List l = new ArrayList();
        //因为 LinkedList 和 ArrayList 都实现了 List 接口,所以我们可以灵活互换
        //直接修改为 LinkedList,对我们的程序没有任何影响
        List l = new LinkedList();
        //自动装箱,适合于 jdk1.5
        l.add(1);
        l.add(3);
        //jdk1.5 以前,必须如下使用
        l.add(new Integer(2));
        l.add(new Integer(4));
        //可以加入重复数据
        l.add(2);
        for (int i = 0; i < l.size(); i++) {
            Integer e = (Integer) l.get(i);
            System.out.print(e + " ");
        }
        System.out.println("");

        l.remove(2);

        Iterator iter = l.iterator();
        while (iter.hasNext()) {
            Integer v = (Integer) iter.next();
            System.out.print(v + " ");
        }
        System.out.println("");

        for (Iterator iter1 = l.iterator(); iter1.hasNext(); ) {
            Integer v = (Integer) iter1.next();
            System.out.print(v + " ");
        }
        System.out.println();

        System.out.println(l.contains(3));
        System.out.println(l.isEmpty());
        System.out.println("");

        Object[] oArray1 = l.toArray();
        for (int i = 0; i < oArray1.length; i++) {
            Integer v = (Integer) oArray1[i];
            System.out.print(v + " ");
        }
        System.out.println("");

        Integer[] iArray = new Integer[l.size()];
        l.toArray(iArray);
        for (int i = 0; i < iArray.length; i++) {
            int v = iArray[i];
            System.out.print(v + " ");
        }
    }

}

output:

  

三、Set接口

3.1、哈希表

        哈希表是一种数据结构,哈希表能够提供快速存取操作。哈希表是基于数组的,所以存在缺点,数组一旦创建将不能扩展。

        正常的数组,如果需要查询某个值,需要对数组进行遍历,只是一种线性查找,查找的速度比较慢。如果数组中的元素值和下标能够存在明确的对应关系,那么通过数组元素的值就可以换算出数据元素的下标,通过下标就可以快速定位数组元素,这样的数组就是哈希表。

一张哈希表:

元素值1011121314151617
元素下标01234567

以上我们示例元素值和下标的关系为:

        元素下标 = 元素值 - 10,此时的示例hashcode就是和数组下标一致了,取得华顺从的方法如下:

//取得 hashCode
pubic int hashCode(int value) {
    return value – 10;
}

有了hashcode后,我们就可以快速定位相应的元素,查找到相应的信息。

3.2、HashSet

        HashSet中的数据是无序的不可重复的。HashSet按照哈希算法存取数据,具有非常好的性能,他的工作原理是这样的,当向HashSet中插入数据的时候,他会调用对象的HashCode得到该对象的哈希码,然后根据哈希码计算出该对象插入到集合的位置。

3.3、代码示例

import java.util.*;

public class Test {
    public static void main(String[] args) {
        //它是无序的,不重复
        Set set = new HashSet();
        set.add("a");
        set.add("b");
        set.add("c");
        set.add("c1");
        set.add("c2");
        set.add("d3");
        set.add("a7");
        //输出是无序的
        for (Iterator iter=set.iterator(); iter.hasNext();) {
            System.out.print(iter.next() + " ");
        }
        //加入重复数据
        set.add("a");
        System.out.println("");
        for (Iterator iter=set.iterator(); iter.hasNext();) {
            System.out.print(iter.next() + " ");
        }
        System.out.println();

        String s1 = "abc";
        String s2 = "abc";
        System.out.println("s1 equals s2 ," + s1.equals(s2));

        //equals 相等,hashcode 一定是相等的
        System.out.println("s1.hashCode = " + s1.hashCode());
        System.out.println("s2.hashCode = " + s2.hashCode());
        String s3 = "ddddd";
        System.out.println("s1 equlas s3," + s1.equals(s3));
        System.out.println("s3.hashCode = " + s3.hashCode());
    }

}

output:

  

3.4、equals和hashCode

下面这段代码通过在HashMap中添加对象,来阐述equals和hashCode的关系。
在我的这篇文章里有关于两者更详细的说明,有兴趣的可以看一下。

代码如下:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";

        Person p2 = new Person();
        p2.name = "李四";

        Person p3 = new Person();
        p3.name = "张三";


        Set set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        for (Iterator iter=set.iterator(); iter.hasNext();) {
            Person p = (Person)iter.next();
            System.out.println("name=" + p.name );
        }

        System.out.println("p1.hashCode=" + p1.hashCode());
        System.out.println("p2.hashCode=" + p2.hashCode());
        System.out.println("p3.hashCode=" + p3.hashCode());
        System.out.println();

        System.out.println("p1 equals p2," + p1.equals(p2));
        System.out.println("p1 equals p3," + p1.equals(p3));
    }

}
class Person {
    String name;
}

output:

以上代码加入了重复的数据,因为 hashCode 是不同的,所以会算出不同的位置。

进一步完善,覆盖equals,代码如下:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";

        Person p2 = new Person();
        p2.name = "李四";

        Person p3 = new Person();
        p3.name = "张三";


        Set set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        for (Iterator iter=set.iterator(); iter.hasNext();) {
            Person p = (Person)iter.next();
            System.out.println("name=" + p.name );
        }

        System.out.println("p1.hashCode=" + p1.hashCode());
        System.out.println("p2.hashCode=" + p2.hashCode());
        System.out.println("p3.hashCode=" + p3.hashCode());
        System.out.println();

        System.out.println("p1 equals p2," + p1.equals(p2));
        System.out.println("p1 equals p3," + p1.equals(p3));
    }

}
class Person {
    String name;

    //覆盖 equals
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof Person) {
            Person p = (Person)obj;
            return this.name.equals(p.name);
        }
        return false;
    }
}

output:

以上代码在重写equals以后虽然能够比较出对象的相同但是仍然插入了重复数据,是因为两个对象的hashCode不同所造成的,所以为了避免插入重复数据必须重写hashCode。

代码示例,只覆盖了hashCode,没有覆盖equals:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";

        Person p2 = new Person();
        p2.name = "李四";

        Person p3 = new Person();
        p3.name = "张三";


        Set set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        for (Iterator iter=set.iterator(); iter.hasNext();) {
            Person p = (Person)iter.next();
            System.out.println("name=" + p.name );
        }

        System.out.println("p1.hashCode=" + p1.hashCode());
        System.out.println("p2.hashCode=" + p2.hashCode());
        System.out.println("p3.hashCode=" + p3.hashCode());
        System.out.println();

        System.out.println("p1 equals p2," + p1.equals(p2));
        System.out.println("p1 equals p3," + p1.equals(p3));
    }

}
class Person {
    String name;

    //覆盖 hashCode
    public int hashCode() {
        return (name==null) ? 0:name.hashCode();
    }
}

output:

可见以上代码还是插入了重复的数据,是因为在插入数据时,首先会比较hashCode,如果相同,再比较equals,只有equals也相同的时候,才会认为重复,因为equals不同,所以不认为是相同对象,再一次没有避免重复插入。

代码进一步改善,同时覆盖hashCode和equals:

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";

        Person p2 = new Person();
        p2.name = "李四";

        Person p3 = new Person();
        p3.name = "张三";


        Set set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        for (Iterator iter=set.iterator(); iter.hasNext();) {
            Person p = (Person)iter.next();
            System.out.println("name=" + p.name );
        }

        System.out.println("p1.hashCode=" + p1.hashCode());
        System.out.println("p2.hashCode=" + p2.hashCode());
        System.out.println("p3.hashCode=" + p3.hashCode());
        System.out.println();

        System.out.println("p1 equals p2," + p1.equals(p2));
        System.out.println("p1 equals p3," + p1.equals(p3));
    }

}
class Person {
    String name;

    //覆盖 hashCode
    public int hashCode() {
        return (name==null) ? 0:name.hashCode();
    }

    //覆盖 equals
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof Person) {
            Person p = (Person)obj;
            return this.name.equals(p.name);
        }
        return false;
    }
}

output:

 

可以看到,在重写hashCode和equals方法以后,终于避免了张三的重复插入。当hashCode相等时会调用equals方法来比较,如果equals比较相等将不把此元素加入Set中。

总结:

        两个对象的equals相等,那么他的hashCode相等,也就是说如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。

        两个对象的equals不相等,那么并不要要求他的hashCode也不相等,也就是说如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能

        一般不建议认为两个对象hashCode相等这两个对象就相等,我们一般用equals来比较两个对象是否相等。

强调:

        向HashSet和HashMap中加入数据时必须同时覆盖hashCode和equals。

        

3.5、TreeSet概述

        TreeSet可以对Set集合进行排序,默认自然排序(升序),但也可以客户化的排序(自定义排序规则)。

3.6、代码示例

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Set set = new TreeSet();
        set.add(9);
        set.add(2);
        set.add(5);
        set.add(1);
        //不能放入重复数据
        set.add(5);
        for (Iterator iter = set.iterator(); iter.hasNext(); ) {
            Integer v = (Integer) iter.next();
            System.out.println(v);
        }
    }

}

output:

 可以看出TreeSet自然排序和不可重复的特点。

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";

        Person p2 = new Person();
        p2.name = "李四";

        Person p3 = new Person();
        p3.name = "张三";

        Set set = new TreeSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);
        for (Iterator iter=set.iterator(); iter.hasNext();) {
            Person p = (Person)iter.next();
            System.out.println("name=" + p.name);
        }
    }
}
class Person {
    String name;
}

output:

出现了错误,因为放到TreeSet中TreeSet都会对其进行排序,那么必须实现Comparable接口但是Person并没有实现。基本类型的包装类和String他们都是可以排序的,他们都实现了Comparab接口。

3.7、实现Comparable接口完成程序

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";
        p1.age = 20;
        Person p3 = new Person();
        p3.name = "张三";
        p3.age = 40;
        Person p2 = new Person();
        p2.name = "李四";
        p2.age = 30;
        Set set = new TreeSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);
        for (Iterator iter = set.iterator(); iter.hasNext(); ) {
            Person p = (Person) iter.next();
            System.out.println("name = " + p.name + " age = " + p.age);
        }
    }
}

class Person implements Comparable {

    String name;
    int age;

    //如果覆盖了 equals,最好保证 equals 和 compareto 在相等情况下的比较规则是一致的
    public int compareTo(Object o) {
        if (o instanceof Person) {
            Person p = (Person) o;
            //升序
            //return (this.age - p.age);
            //降序
            return (p.age - this.age);
        }
        throw new IllegalArgumentException("非法参数,o=" + o);
    }
}

output:

 3.8、实现Comparator接口完成排序

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";
        p1.age = 20;
        Person p3 = new Person();
        p3.name = "张三";
        p3.age = 40;
        Person p2 = new Person();
        p2.name = "李四";
        p2.age = 30;

        Comparator personComparator = new PersonComparator();

        Set set = new TreeSet(personComparator);
        set.add(p1);
        set.add(p2);
        set.add(p3);
        for (Iterator iter = set.iterator(); iter.hasNext(); ) {
            Person p = (Person) iter.next();
            System.out.println("name = " + p.name + " age = " + p.age);
        }
    }
}

class Person {

    String name;
    int age;

}

//实现 Person 的比较器
//Comparator 和 Comparable 的区别?
//Comparable 是默认的比较接口,Comparable 和需要比较的对象紧密结合到一起了
//Comparator 可以分离比较规则,所以它更具灵活性
class PersonComparator implements Comparator {
    public int compare(Object o1, Object o2) {
        if (!(o1 instanceof Person)) {
            throw new IllegalArgumentException("非法参数,o1=" + o1);
        }
        if (!(o2 instanceof Person)) {
            throw new IllegalArgumentException("非法参数,o2=" + o2);
        }
        Person p1 = (Person) o1;
        Person p2 = (Person) o2;
        return p1.age - p2.age;
    }
}

 3.9、Comparable 和 Comparator 的区别?

3.9.1、Comparable

Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:

1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数

2、比较者等于被比较者,那么返回0

3、比较者小于被比较者,那么返回负整数

3.9.2、Comparator


Comparator可以认为是是一个外比较器,个人认为有两种情况可以使用实现Comparator接口的方式:

1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较

2、一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式

Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

1、o1大于o2,返回正整数

2、o1等于o2,返回0

3、o1小于o3,返回负整数

3.9.3、总结

1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法

2、实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。

当然,这不是鼓励用Comparator,意思是开发者还是要在具体场景下选择最合适的那种比较器而已。

四、Map接口

4.1、Map概述

        Map中可以放置键值对,也就是每一个元素都包含键对象和值对象,Map实现较为常用的为HashMap,HashMap对键对象的存取和HashSet一样,仍然采用的是哈希算法,所以如果使用自定义类作为Map的键对象,必须复写equals和hashCode方法。

4.2、HashMap

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("1001", "张三");
        map.put("1002", "李四");
        map.put("1003", "王五");

        //采用 entrySet 遍历 Map
        Set entrySet = map.entrySet();
        for (Iterator iter = entrySet.iterator(); iter.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iter.next();
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }

        System.out.println("");

        //取得 map 中指定的 key
        Object v = map.get("1003");
        System.out.println("1003==" + v);
        System.out.println("");

        //如果存在相同的条目,会采用此条目替换
        //但 map 中始终保持的是不重复的数据
        //主要依靠 key 来判断是否重复,和 value 没有任何关系
        map.put("1003", "赵六");

        //采用 keySet 和 get 取得 map 中的所有数据
        for (Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
            String k = (String) iter.next();
            System.out.println(k + ", " + map.get(k));
        }
    }
}

output:

 4.3、HashMap采用自定义类作为Key

import java.util.*;

public class Test {
    public static void main(String[] args) {
        IdCard idCard1 = new IdCard();
        idCard1.cardNo = 2;
        Person person1 = new Person();
        person1.name = "张三";

        IdCard idCard2 = new IdCard();
        idCard2.cardNo = 3;
        Person person2 = new Person();
        person2.name = "李四";

        IdCard idCard3 = new IdCard();
        idCard3.cardNo = 2;
        Person person3 = new Person();
        person3.name = "张三";

        Map map = new HashMap();
        map.put(idCard1, person1);
        map.put(idCard2, person2);
        map.put(idCard3, person3);

        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iter.next();
            IdCard idCard = (IdCard) entry.getKey();
            Person person = (Person) entry.getValue();
            System.out.println(idCard.cardNo + ", " + person.name);
        }
    }
}

class IdCard {
    int cardNo;
}

class Person {
    String name;
}

output:

可以看到,上述代码加入了重复的数据,是因为HashMap的底层实现采用可hash表,所以Map的key必须覆盖hashCode和equals方法。 

4.4、HashMap覆盖equals和hashCode方法

import java.util.*;

public class Test {
    public static void main(String[] args) {
        IdCard idCard1 = new IdCard();
        idCard1.cardNo = 2;
        Person person1 = new Person();
        person1.name = "张三";

        IdCard idCard2 = new IdCard();
        idCard2.cardNo = 3;
        Person person2 = new Person();
        person2.name = "李四";

        IdCard idCard3 = new IdCard();
        idCard3.cardNo = 2;
        Person person3 = new Person();
        person3.name = "张三";

        Map map = new HashMap();
        map.put(idCard1, person1);
        map.put(idCard2, person2);
        map.put(idCard3, person3);

        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iter.next();
            IdCard idCard = (IdCard) entry.getKey();
            Person person = (Person) entry.getValue();
            System.out.println(idCard.cardNo + ", " + person.name);
        }
    }
}

class IdCard {
    int cardNo;

    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof IdCard) {
            IdCard idCard = (IdCard) obj;
            if (this.cardNo == idCard.cardNo) {
                return true;
            }
        }
        return false;
    }

    public int hashCode() {
        return new Long(cardNo).hashCode();
    }
}

class Person {
    String name;
}

output:

以上代码执行结果正确,没有插入重复的数据。

4.5、TreeMap 

        TreeMap可以对Map中的key进行排序,如果Map中的lkey采用的是自定义类那么需要实现Comaprable或者Com怕让投入接口完成排序。

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Map map = new TreeMap();

        map.put("1003", "王五");
        map.put("1001", "张三");
        map.put("1002", "李四");

        for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iter.next();
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
    }
}

output:

排序输出。 

五、Collections工具类

        Collections位于java.util包中,提供了一系列实用的方法,如:对集合排序,对集合中的内容查找等。

import java.util.*;

public class Test {
    public static void main(String[] args) {
        // 对ArrayList操作
        List l = new ArrayList();
        l.add(5);
        l.add(1);
        l.add(4);
        l.add(2);

        for (Iterator iter = l.iterator(); iter.hasNext(); ) {
            System.out.print(iter.next() + " ");
        }
        System.out.println("");

        Collections.sort(l);

        for (Iterator iter = l.iterator(); iter.hasNext(); ) {
            System.out.print(iter.next() + " ");
        }
        System.out.println("");

        // 对Set操作
        Set set = new HashSet();
        set.add(10);

        set.add(1);
        set.add(4);
        set.add(9);
        //不能直接对 set 排序
        //Collections.sort(set);
        List setList = new ArrayList(set);
        Collections.sort(setList);
        for (Iterator iter = setList.iterator(); iter.hasNext(); ) {
            System.out.print(iter.next() + " ");
        }
        System.out.println("");

        // 寻找下标
        int index = Collections.binarySearch(setList, 9);
        System.out.println("index=" + index);
        System.out.println("");

        // 反转操作
        Collections.reverse(setList);
        for (Iterator iter = setList.iterator(); iter.hasNext(); ) {
            System.out.print(iter.next() + " ");
        }
    }
}

output:

参考链接:

http://www.bjpowernode.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值