码迷,mamicode.com
首页 > 编程语言 > 详细

JavaSE:集合总结(Collection,Map)

时间:2015-03-06 01:05:27      阅读:331      评论:0      收藏:0      [点我收藏+]

标签:javsse   集合   记录   总结   

今天来总结JavaSE部分的集合。首先来从整体来看:
技术分享
我们主要要学习的内容:
技术分享
Collection:

Collection(接口): java.util.Collection
|-- List(子接口) :
    |--ArrayList
    |--LinkedList
    |--Vector
|-- Set(子接口)  :
    |--AbstracSet(子接口)
        |--HashSet
            |--LinkedHashSet
    |--SortedSet(子接口)
        |--TreeSet
|-- Queue(子接口) :    

Map:

Map:java.util.Map
Map(接口)
    |--HashMap
        |--linkedHashMap
    |--Hashtable
        |--Properties
    |--TreeMap

1.Collection:

因为Collection是所有集合类的父接口,所以它中的方法子接口和具体实现类都会继承或实现,那么先来学习Collection:
常用到的方法:

add(),addAll(),remove(),clear()--> 这两组方法对比着学习记忆。
contains(),isEmpty()
size(), toArray(),iterator()
具体的作用自己去测试下吧。

接下来学习:
1 List子接口,要明白它的特点是:元素有序且可以重复,怎么保证它是有序的呢?通过索引来保证的。
所以 List集合里添加了根据索引来操作集合元素的方法:

get(),set()
indexOf(),lastIndexOf()
subList()
listIterator()

再看看这个结构,我们要学的就是这些内容:

|-- List(子接口) :
    |--ArrayList
    |--LinkedList
    |--Vector

1.1 ArrayList:
是List接口的典型实现类,可以把它看成是一个可变长度的数组
相比于List,也没有增加新的方法,只是实现了List中的方法

注意:
Arrays.asList() 返回的不是ArrayList,而是一个固定长度的List

1.2 LinkedList:
新增加了链表来维护元素的位置(适用于频繁的插入和删除操作)
既然新增了链表结构,那么它肯定新增了方法:

addFirst(),addLast()
getFirst(),getLast()
removeFirst(),removeLast()

1.3 Vector:
是一个古老的类,它是线程安全的,但是效率低于ArrayList,所以现在很少使用。
操作的是element

2 Set 子接口

|-- Set(子接口)  :
    |--AbstracSet(子接口)
        |--HashSet
            |--LinkedHashSet
    |--SortedSet(子接口)
        |--TreeSet

和List的特点恰恰相反,Set中的元素不能是重复的,但是可以是无序的。
Set中并没有提供额外的方法

问题:怎么来保证两个元素是不能重复的?
solution:首先要通过hashCode()方法来比较两个元素的哈希值是否相同,如果相同,再通过equals()来判断他们的内容是否相等,若相等,则重复。

当然只有具体的实现类才有承接对象的能力,而Set的这个特点对于它的实现类都是适用的。

2.1 HashSet:
是Set接口的典型实现类,通过Hash算法来存取数据,具有很好的查找和存取性能。

2.2 LinkedHashSet:
HashSet的子类,同时增加了链表结构来维护元素的次序,使元素看起来和插入时的顺序一致。
因为增加了链表结构,所以插入的时候效率降低了,而迭代的时候效率提高了

2.3 TreeSet:
是Sorted的子接口,能实现自定义排序
新增的方法:

comparator(),first(),last(),lower(),higer(),subSet(),headSet(),tailSet()

说实话,这么多方法,我只用到了comparator()!!!
自然排序:
TreeSet添加的对象,必须实现Comparable接口,同时实现compareTo()方法

定制排序:
在TreeSet的构造器中指定排序方式
①可以通过Comparator的实现类,这个实现类得实现compare()方法
②可以通过匿名内部类来直接获取Comparator接口的实例
③可以在构造器中传入匿名对象。

/*
     * 1.请从键盘随机输入10个整数保存到List中,并按倒序、从大到小的顺序显示出来
     * 
     * 2.请把学生名与考试分数录入到Map中,并按分数显示前三名成绩学员的名字。
     */
    @Test
    public void test3(){
        scan = new Scanner(System.in);
        List<Integer> list = new ArrayList<Integer>();
        for(int i = 0; i < 10; i++){
            list.add(scan.nextInt());
        }

        Collections.sort(list);
        Collections.reverse(list);
        for(Integer i : list){
            System.out.println(i);
        }
    }
    /*
     * 1. 定义一个Employee类, 该类包含:private成员变量name,age,birthday,其中 birthday 为 MyDate
     * 类的对象; 并为每一个属性定义 getter, setter 方法; 并重写 toString 方法输出 name, age, birthday
     * 
     * MyDate类包含: private成员变量month,day,year;并为每一个属性定义 getter, setter 方法;
     * 
     * 创建该类的 5 个对象,并把这些对象放入 TreeSet 集合中
     * 分别按以下两种方式对集合中的元素进行排序,并遍历输出:
     * 
     * 1). 使Employee 实现 Comparable 接口,并按 name 排序 2). 创建 TreeSet 时传入
     * Comparator对象,按生日日期的先后排序。
     * 
     *
     */
    @SuppressWarnings("unused")
    @Test
    public void test2() {
        class MyCommparator implements Comparator<Employee> {

            @Override
            public int compare(Employee o1, Employee o2) {
                if (o1.equals(o2))
                    return 0;
                else if (o1.getName().equals(o2.getName()))
                    return new Integer(o1.getAge()).compareTo(new Integer(o2
                            .getAge()));
                else
                    return o1.getName().compareTo(o2.getName());
            }

        }
        Comparator<Employee> cpt = new Comparator<Employee>() {

            @Override
            public int compare(Employee o1, Employee o2) {
                if (o1.equals(o2))
                    return 0;
                else if (o1.getName().equals(o2.getName()))
                    return new Integer(o1.getAge()).compareTo(new Integer(o2
                            .getAge()));
                else
                    return o1.getName().compareTo(o2.getName());
            }
        };
        TreeSet<Employee> ts = new TreeSet<Employee>(
                new Comparator<Employee>() {

                    @Override
                    public int compare(Employee o1, Employee o2) {
                        if (o1.equals(o2))
                            return 0;
                        else if (o1.getName().equals(o2.getName()))
                            return new Integer(o1.getAge())
                                    .compareTo(new Integer(o2.getAge()));
                        else
                            return o1.getName().compareTo(o2.getName());
                    }
                });
        ts.add(new Employee("zhangsan", 23, new MyDate(12, 12, 1993)));
        ts.add(new Employee("zhaoliu", 27, new MyDate(10, 11, 1977)));
        ts.add(new Employee("wangwu", 25, new MyDate(22, 1, 1989)));
        ts.add(new Employee("zhaoliu", 27, new MyDate(3, 2, 1993)));
        ts.add(new Employee("tianqi", 28, new MyDate(2, 4, 1991)));

        for (Employee t : ts) {
            System.out.println(t);
        }
    }

    // Collection: List:arrayList linkedList / Set: hashSet->linkedHashSet
    // treeSet
    @Test
    public void test1() {
        String[] str = new String[5];
        for (String s : str) {
            s = "atguigu";
            System.out.println(s);
        }
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }
    }

    @Test
    public void test() {
        List<Object> list = new ArrayList<Object>();
        list.add(123);
        list.add("zhang");

        for (Object l : list) {
            System.out.println(l);
        }

        Iterator<Object> itor = list.iterator();
        while (itor.hasNext()) {
            System.out.println(itor.next());
        }

        ListIterator<Object> itor1 = list.listIterator();
        itor1.add("lisi");
        while (itor1.hasNext()) {
            System.out.println(itor1.next());
        }

    }
/*1. 定义一个Employee类,
 该类包含:private成员变量name,age,birthday,其中 birthday 为 MyDate 类的对象;
 并为每一个属性定义 getter, setter 方法;
 并重写 toString 方法输出 name, age, birthday
 */
public class Employee{
    private String name;
    private int age;
    private MyDate birthday;

    public Employee() {
    }

    public Employee(String name, int age, MyDate birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    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;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + ", age=" + age + ", birthday="
                + birthday + "]";
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((birthday == null) ? 0 : birthday.hashCode());
        return result;
    }

//  @Override
//  public int compareTo(Employee o) {
//      if(this == o)
//          return 0;
//      else if(this.getName().equals(o.getName()))
//          return new Integer(this.age).compareTo(new Integer(o.age));
//      else
//          return this.getName().compareTo(o.getName());
//  }
}
//private成员变量month,day,year;并为每一个属性定义 getter, setter 方法;
public class MyDate {
    private int month;
    private int day;
    private int year;

    public MyDate() {
    }

    public MyDate(int month, int day, int year) {
        this.month = month;
        this.day = day;
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    @Override
    public String toString() {
        return "MyDate [month=" + month + ", day=" + day + ", year=" + year
                + "]";
    }

}

3 Queue
是一个古老的接口,是线程安全的,效率低,现在很少使用

到这里Collection集合就先告一段落。
接下来该遍历了:

4 集合元素的遍历:
①因为List中有索引,我们可以通过最基本的for循环来完成,只适用于List集合
②增强for循环,适用于所有集合元素
迭代器:Iterator

注意:①迭代器本身没有承接对象的能力,必须通过集合来获取
     ②在使用iterator.next()之前,必须使用iterator.hasNext()进行判断,否则会报NoSuchElementException异常
     ③Enumeration是Iterator的古老版本

2.Map

Map(接口)
    |--HashMap
        |--LinkedHashMap
    |--Hashtable
        |--Properties
    |--TreeMap

1 Map
首先来说,Map是和Collection同一级的接口,并列存在,并不是Collection的子接口。Map用来保存具有映射关系的数据:键值对(key->value)
key中不允许有重复的值,可以看成是一个Set集合,判断是否重复和Set相同;而值得话可以重复

注意理解映射:我昨天的博客“JDBC的进化2“中所说的ORM就是一种映射关系。还记得么?回顾一下:ORM:对象关系映射,没一张表对应这一个类,每一列对应一个属性,每一行对应一个对象。

方法:

添加、删除操作:
Object put(Object key,Object value)
Object remove(Object key)
void putAll(Map t)
void clear()

元视图操作的方法:
Set keySet()
Collection values()
Set entrySet()

元素查询的操作:
Object get(Object key)
boolean containsKey(Object key)
boolean containsValue(Object value)
int size()
boolean isEmpty()
boolean equals(Object obj)

1.1 HashMap
①允许null键,null值,但是不能保证映射的顺序
②判断key值是否重复,和HashSet相同

1.1.1 LinkedHashMap
类似于HashSet和LinkedHashSet的关系

1.2 TreeMap
我是这样理解的,类比于TreeSet,是TreeSet的键值对形式,可以实现自然排序和定制排序

1.3 Hashtable
又是一个古老的类,线程安全,现在很少使用,不允许插入null键值,其余和HashMap类似,我们主要用到它的子类Properties

1.3.1 Properties
是Hashtable的子类,它中的key和value都是String类型的,我们经常用它来读取配置文件信息

Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);

Ok,Map也结束了。。。

3 工具类(Collections)
可以操作List,Set,Map的一个工具类
它中的方法全为静态方法:(学了这么多了,一提工具类,我们就知道它都是静态的方法,扩展一下,以后我们自己也可以创建工具类,来操纵我们具体的实体类,你说是不是这样的呢?)
方法:

排序操作:
reverse()
shuffle()
sort()
sort(List, Comparator)指定排序方式
swap()
查找和替换:
max(),min()
frequency() 次数
copy()
replaceAll() 新值替换旧值

到此为止,是不是以为就总结完了?No,其实还没有开始总结,上面的仅仅是回顾。我们来总结。

总结:

没有好的作图工具(思维导图有很大的局限性,可能也是我研究的不够深),我只能是手画了,有时候图形能表达的东西更多,也更容易理解记忆。
技术分享
先来这一张整体的
技术分享
技术分享
手机像素有点渣,看不清第一张的,可以看下面的两张。
画的不好,但是我认为可以表达意思了。
来,开始的分析:
我是这样分析的,从整体再到具体(思维),先纵向再横向:
1.Collection 和Map,有什么联系和区别?
联系:Collection和Map都是java.util下的集合接口,Collection和Map属于同一层次。
区别:Collection中存放的是一个值(只能可以是任意的对象),而Map中存放的是键值对(当然键和值,也只能可以是任意对象)
*再往下走,忘画一个Queue了。
2.List和Set和Queue有什么区别和联系
联系:都是Collection的子接口。
区别:List中的元素是有序的,可以重复的,而Set中的元素是无序的,不可以重复的;Queue是一个古老的类,是线程安全的,现在很少使用。
*Map和他俩不是一个层次的,无法进行比较
3.ArrayList,LinkedList和Vector的区别和联系
联系:都是List的实现类
区别:LinkedList相比于ArrayList增加了链表结构来维护元素的顺序,适用于频繁的插入和删除操作,而迭代速度没有ArrayList快。Vector是一个古老的实现类,是线程安全的,它中的方法和ArrayList类似,但是效率低于ArrayList

*再来比较Set中各个元素
4.HashSet,LinkedHashSet,和TreeSet有什么区别和联系?
联系:HashSet和TreeSet是Set接口的实现类,LinkedHashSet是HashSet的子类。
区别:HashSet中的对象需要重写hashCode()和equals()方法,来确定他们是否重复,TreeSet中添加的对象需实现Comparable接口,或是在TreeSet构造器中指定Comparator接口的实例。相比于HashSet可以插入任意的无序且不重复的元素来说,TreeSet有自己的排序方式(自然排序和定制排序)。LinkedHashSet相比于HashSet,增加了链表结构,插入和删除数据性能要低于HashSet,但是迭代性能要高于HashSet。

*到比较Map了
5.HashMap和TreeMap,以及Hashtable的区别和联系?
联系:都是Map接口的实现类
区别:HashMap中的键都是Set集合,但是可以将HashMap中的键认为成是HashSet,而TreeMap中的键是TreeSet,TreeMap可以按TreeSet中的排序方式来排序。相比于HashMap,Hashtable是一个古老的实现类,它是线程安全的,它不允许插入null键和null值,而HashMap则允许。

最后就是整体的横向对比:
各个实现类的适用场景以及效率对比:
首先进行分类:将List,Set和Map分开,因为存放的内容不相同。
1.List内部比较:
ArrayList: 有索引,遍历相对来说较快,效率高;插入和删除时,需要挪动很多数据,所以较慢,效率低。
LinkedList:有索引,有链表,遍历快,插入和删除效率高,但是增加链表后,需要维护链表也需要一定的资源。
2.Set内部比较
HashSet:无序,插入快,删除快,遍历,非常慢。
TreeSet:插入和删除,和遍历效率不确定,因为不知道排序的算法有多么复杂,但是我认为,总体来说它的效率不会高。
LinkedHashSet:插入和删除效率要低于HashSet,因为增加了链表结构,但是迭代速度增加了不少。算是一种平衡吧。用来平衡效率
3.List和Set做比较
List:有索引,相对来说遍历较快,而插入,删除较慢
Set:无索引,插入和删除非常快,遍历非常慢。

这几个效率的比较是我自己根据他们的理解来判断的,没有学过数据结构和算法,等我学完后,就能明确的给出一个效率了,得考虑它们的数据结构和算法复杂度。有兴趣的朋友可以和我一起研究。
4.总结各适用于什么场景:
上一张图吧(又是自己画的!):
技术分享

5.Map就不做说明了。对比上面的Set,相信你自己也能明白了。
HashMap
TreeMap
LinkedHashMap:

差点忘了,还有一个要补充的:
ListIterator 和Iterator的区别
ListIterator是Iterator的子接口,只适用于List,它可以在遍历的时候增加,设置,移除值,同时它可以逆向遍历。(逆向遍历我没明白,必须将它的指针移到最后,你才可以逆向遍历,相当于,你先正向遍历后,将指针移到最后,才能逆向遍历)

@Test
    public void test5(){
        // when the element is "def", insert "bbb" or modify  to "bbbb", and remove "def";
        List<String> list = new ArrayList<String>();
        list.add("abc");
        list.add("def");
        list.add("ghi");
        ListIterator<String> li = list.listIterator();
        while(li.hasNext()){
            String str = li.next();
            if(str.equals("def")){
//              li.add("bbb");
                li.set("aaaa");
                li.remove();
            }
        }
        System.out.println(list);

    }

Ok,总算是就集合总结完了,有耐心看完的朋友,相信你会收获不小。当然,我这总结的可能也会有很多的漏洞,欢迎大家指点。睡觉了。

JavaSE:集合总结(Collection,Map)

标签:javsse   集合   记录   总结   

原文地址:http://blog.csdn.net/sloverpeng/article/details/44090597

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!