JavaSE:集合总结(Collection,Map)

今天来总结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,总算是就集合总结完了,有耐心看完的朋友,相信你会收获不小。当然,我这总结的可能也会有很多的漏洞,欢迎大家指点。睡觉了。

时间: 2024-08-09 23:55:10

JavaSE:集合总结(Collection,Map)的相关文章

[javaSE] 集合框架(Map概述)

Map集合,将key对象映射到value对象 三个主要的子类:Hashtable,HashMap,TreeMap Hashtable:底层是哈希表数据结构,不允许使用null值,线程同步 HashMap:底层是哈希表数据结构,允许使用null值,线程不同步 TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键排序 使用keySet()方法遍历Map集合 调用Map对象的keySet()方法,得到Set对象,这里存储的是所有的键 import java.util.HashM

一、javaSE (十七)set集合、Collection集合、针对Collection集合我们到底使用谁、在集合中常见的数据结构

1:set集合(理解) (1)Set集合的特点 无序,唯一 (2) Hashset集合(掌握) A:底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法: hashCode()和equals() 执行顺序 首先比较哈希值是否相同 相同:继续执行equals()方法 返回true:元素重复了,不添加 返回fa1se:直接把元素添加到集合 不同:就直接把元素添加到集合 C:如何保证元素唯一性的呢? 由 hashcode()和equals()保证的 D:开发的时候,代码非常的简单

javaSE集合框架

7.集合框架  集合: Collection接口   : -List接口  (有序的,通常允许重复)   -实现类:ArrayList(用可变数组实现,不是同步的(线程不安全)) :适合查找,添加  LinkedList(双向链表的实现,不是同步的):适合插入,删除    Vector(用可变数组实现,同步的):适合查找,添加 -Set接口  (无序的,不允许重复) -实现类:HashSet(无序的,不同步,不允许重复)     TreeSet(有序的,不同步,不允许重复) Collection

集合框架Collection(一)

1.1集合概念 1.1.1集合:是java中提供的一种容器,用来存储多个数据 数组和集合的区别:1.数组的长度是固定的,集合的长度是可变的:2.数组中存储数据类型是同一类型,可以存储基本数据类型值,集合存储的都是对象,不能存储基本数据类型           值,对象数据类型可以不一致,一般在开发中使用集合存储. 1.1.2   集合框架:javaSE提供了各种API(方法). 集合按照存储结构可以分为两大类:1.单列集合java.util.Collection  2.双列集合java.util

Collection Map Java数据结构

Collection Map 框架图 Collection          接口的接口   对象的集合 ├ List                   子接口      按进入先后有序保存   可重复 │├ LinkedList                接口实现类   链表   插入删除   没有同步   线程不安全 │├ ArrayList                  接口实现类   数组   随机访问   没有同步   线程不安全 │└ Vector             

3.9 java基础总结集合①LIst②Set③Map④泛型⑤Collections

集合①LIst②Set③Map④泛型⑤Collections 一.List:有顺序,可重复实现类:1.ArrayList 广泛,适用于查询,增删不频繁的(类似数组,其长度可按需增大,增删效率慢)2.LinkedList 中间频繁增删的,查询效率低(双向链表,先进先出,不支持随机查找,必须重头开始查找,效率低)3.Vector 类似ArrayList,线程安全,性能低 二.Set:没有顺序,不可重复最多存一个null实现类:1.HashSet 速度快,不排序2.TreeSet 速度慢,内部排序,看

黑马程序员-集合框架(Map和Collections)

--Java培训.Android培训.iOS培训..Net培训.期待与您交流!--- 一.概述 Map是一种存储键值对的存储容器,而且保证键的唯一性.提供一种以"键"标识"值"的数据存储方式.接口形式为:Map<K,V>,其中K是此映射所维护的键的类型,V是映射值的类型.其有两个常用子类,HashMap和TreeMap,另有HashTable与HashMap功能类似,是早期版本.三者特点与不同如下: HashMap:JDK1.2版本出现,底层使用哈希表数

Java集合之Collection接口

java的集合分为三大接口,分别是Collection,Map,Iterator,集合接口和类在java.util包中,此次主要介绍三大接口之一的Collection接口. 一些Collection允许有重复元素,而另一些则不允许,一些Collection是有序的,另一些则是无序的.Collection不提供接口的任何直接实现,它提供更加具体的子接口List和Set. 1.List接口 List是有序的集合,此接口的用户队列表的每一个元素的插入位置进行精确的控制,可以根据元素的整数索引访问元素,

Java 集合系列 08 Map架构

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列 05 Vector详细介绍(源码解析)和使用示例 Java 集合系列 06 Stack详细介绍(源码解析)和使用示例 Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和

Java中集合List,Map和Set的区别

Java中集合List,Map和Set的区别 1.List和Set的父接口是Collection,而Map不是 2.List中的元素是有序的,可以重复的 3.Map是Key-Value映射关系,且Key不能重复 4.Set中的元素是无序的,不可重复的