【Java学习笔记】类集框架

Java集合

概述

Java中集合可分为Set、List、Queue、Map四种,Set代表无序、不可重复的集合;List代表有序、重复的集合;Queue代表一种队列集合;Map代表具有映射关系的集合(键值对)。

1)集合类于数组的区别

  • 数组既可以是基本类型的值,也可以是对象;
  • 集合里只能保存对象(虽然集合里不能放基本类型的值,但Java支持自动装箱)。

2)集合继承关系图

这里写图片描述
这里写图片描述

Collection类

1)常用方法

No 方法名称 说明
1 public boolean add(E e) 向集合里添加一个普通元素
2 public boolean addAll(Collection c) 追加一个集合
3 public void clear() 清空集合
4 public boolean contains(Object o) 判断是否包含有指定的内容
5 public boolean isEmpty() 判断是否是空集合
6 public boolean remove(Object o) 删除对象
7 public int size() 取得集合中元素保存的个数
8 public Object[] toArray() 将集合变成对象数组保存
9 Iterator iterator() 为Iterator接口实例化

contains()与remove()方法需要equals()支持。Collection接口几乎不会使用了,而主要使用List(允许重复)与Set(不允许重复)子类。

List集合

大量的扩充了Collection接口的方法。

1)常用方法

No 方法名称 说明
1 public E get(int index) 取得索引编号的内容
2 public E set(int index, E element) 修改指定索引编号的内容
3 public ListIterator listIterator() 为ListIterator接口实例化

由于List本身是属于接口的,所以必须存在有子类(ArrayList或Vector)才能使用此接口进行操作。

2)ArrayList与Vector的区别?

No 区别点 ArrayList Vector
1 推出时间 JDK1.2推出 JDK1.0推出
2 性能 采用异步处理 采用同步处理
3 数据安全 非线程安全 线程安全
4 输出 Iterator、ListIterator、foreach Iterator、ListIterator、foreach、Enumeration

3)总结

  • List中的数据保存顺序就是数据的添加顺序;
  • List集合中可以保存有重复的元素;
  • List子接口比Collection接口扩充了一个get()方法,使得List可以通过索引访问集合的元素内容;
  • List选择子类就使用ArrayList。

Set集合

Set接口并不像List接口那样对Collection接口进行了扩充,而只是进行了简单的继承。
set集合类似一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。Set集合不允许包含相同的元素,如果试图将相同的元素加入同一个Set集合中,则添加操作失败。Set集合有HashSet、TreeSet和EnumSet三个实现类。

HashSet类

HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。

1)特点

  • 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
  • HashSet不是同步的,如果多个线程同时访问和修改一个HashSet,则必须通过代码来保证其同步。
  • 集合元素之可以是null。
  • HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且这个对象的hashCode()方法返回值也相等。

LinkedHashSet类

LinkedHashSet集合同样也是根据元素的hashCode值来决定元素的存储位置,但他同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。所以当我们遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。

LinkedHashSet需要维护元素的插入顺序,所以性能略低于HashSet的性能。但在遍历Set里的全部元素时将有很好的性能。

TreeSet类

TreeSet类主要依靠Comparable接口中的compareTo()方法判断,如果返回的是0,那么它就会被认为是重复数据,不会被保存。

一般不会使用。

Map接口

用于保存一对关联数据(key = value),即键值对,可以使用Map接口实现此类数据的保存。可以通过key查找value。Map存放数据的目的主要是为了信息查找。

1)常用方法

No 方法名称 说明
1 public V put(K key, V value) 向集合中保存数据
2 public V get(Objet key) 根据key查找对应的value数据
3 public Set

HashMap

public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put(null, 0);       //可以存null
    map.put("ONE", 1);
    map.put("TWO", 2);
    map.put("THREE", 3);
    map.put("TWO", 22);     //key重复项
    System.out.println(map);
    System.out.println(map.get("TWO"));     //覆盖后的value值,返回22
    System.out.println(map.get(null));      //返回0
    System.out.println(map.get("FOUR"));    //不存在的key值,返回null

    //获得所有的Key,并输出
    Set<String> set = map.keySet();
    Iterator<String> it = set.iterator();
    while(it.hasNext()) {
        System.out.println(it.next());
    }
}

特点:

  • HashMap集合时无序的;
  • key重复时,旧的value会被新的value覆盖。

Hashtable

在JDK1.0时提供的

public static void main(String[] args) {
    Map<String, Integer> map = new Hashtable<String, Integer>();
    map.put("one", 1);
    map.put("two", 2);
    map.put("three", 3);
    map.put("three", 3);
    //错误
    map.put("Four", null);   //value不能为null
    map.put(null, 4);       //key不能为null

    System.out.println(map);
}

Hashtable与HashMap使用起来是类似的,但Hashtable 的key与value都不能设置为null。

HashMap与Hashtable 的区别

No 区别点 HashMap Hashtable
1 推出时间 JDK1.2推出 JDK1.0推出
2 性能 采用异步处理 采用同步处理
3 数据安全 非线程安全 线程安全
4 设置null 允许key与value为null 不允许key与value为null

Map的输出问题

Map接口与并没有返回Iterator接口对象的方法,所以如果想要使用Iterator输出Map集合,还需要经过一定的转化。

1)Map.Entry

public static interface Map.Entry<K, V>

而在这个内部接口中,定义了两个get()与set()方法:

  • public K getKey();
  • public V getValue();

2)输出Map的步骤:

  • 利用Map接口的entrySet()方法将Map集合变为Set集合,里边的泛型是Map.Entry;
  • 利用Set集合中的iterator()方法将Set集合进行Iterator输出;
  • 每一次Iterator循环去除的都是Map.Entry接口对象,利用此对象进行key与value的取出。

3)示例

public static void main(String[] args) {
    Map<String, Integer> map = new Hashtable<String, Integer>();
    map.put("ONE", 1);
    map.put("TWO", 2);
    map.put("THREE", 3);

    //将Map集合变为Set集合,为了使用iterator()方法
    Set<Map.Entry<String, Integer>> set = map.entrySet();
    //创建iterator对象
    Iterator<Map.Entry<String, Integer>> it = set.iterator();
    //循环取出
    while(it.hasNext()) {
        Map.Entry<String, Integer> em = it.next();
        System.out.println(em.getKey() + " = " + em.getValue());
    }
}

Map集合中的key

当我们使用自定义的类型来做Map的key值时,一定要重写Object类之中的hashCode()与equals()方法,这有靠这两个方法才能够确定元素是否重复,才能够在Map中查找到。

所以在使用Map时,String类型是首选的key类型,尽量少用自定义的类型作为key。

集合的输出

主要支持四种输出方式:Iterator、ListIterator、Enumeration、foreach。以Iterator与Enumeration为主。

迭代输出——Iterator(核心)

Iterator接口也是Java集合框架的成员,它主要由用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。修改迭代遍历Iterator的值对集合元素本身不会产生影响。

1)常用方法

No 方法名称 说明
1 public boolean hasNext() 如果被迭代的集合元素还没有被遍历完,则返回true
2 public Object next() 返回集合里的下一个元素

2)遍历集合示例

public static void main(String[] args) {
    //创建集合,并添加数据
    List<String> book = new ArrayList<String>();
    book.add("Compute Network");
    book.add("Clean Code");
    book.add("Java");  

    //迭代输出
    Iterator it = book.iterator();
    while(it.hasNext()) {
        String bookName = (String)it.next;
        System.out.println(bookName);
        if(book.equals("Clean Code")) {
            it.remove();    //将"Clean Code"从集合中移除
        }
    }

    //遍历集合
    book.forEach(str -> System.out.println(str));

    //foreach输出
    //ArrayList实现了get()方法,所以可以通过索引进行访问
    for(int i =0; i < book.size(); i++) {
        String str = book.get(i);
        System.out.println(str);
    }
}

3)双向迭代

Iterator只提供从前往后的迭代输出,而我们可以使用Iterator的子接口——ListIterator来实现从后向前的迭代输出。

No 方法名称 说明
1 public boolean hasPrevious() 判断是否有前一个元素
2 public E previous() 取得前一个元素

ListIterator是专门为List子接口定义的输出接口,它只能通过List来获得ListIterator的实例。

public static void main(String[] args) {
    List<String> book = new ArrayList<String>();
    book.add("Compute Network");
    book.add("Clean Code");
    book.add("Java");

    ListIterator<String> it = book.listIterator();
    System.out.println("由前向后进行输出:");
    while(it.hasNext()) {
        String bookName = (String)it.next();
        System.out.println(bookName);
    }

    System.out.println("由后向前进行输出:");
    while(it.hasPrevious()) {
        String bookName = (String)it.previous();
        System.out.println(bookName);
    }
}

如果要想实现由后向前输出,必须得先由前向后输出。(如果将以上示例将输出代码的顺序交换,就会发生没有值的错误)

foreach输出

我最喜欢的还是foreach循环遍历,简洁。

public static void main(String[] args) {
    //创建集合,并添加数据for(Object obj : books) {
        String bookName = (String)obj;
         System.out.println(bookName);
    }
}

Enumeration输出

在JDK1.0时所推出的输出接口

1)常用方法

NO 方法名称 说明
1 public boolean hasMoreElements() 判断是否有下一个元素
2 public E nextElement() 取出当前元素

取得Enumeration接口的实例只能通过Vector子类。

Collections工具类

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    Collections.addAll(list, "A","B","C","D");      //追加
    Collections.reverse(list);                  //反转
    System.out.println(list);
}

1)Collection与Collections的区别?

  • Collection是集合操作的接口;
  • Collections是结合操作的工具类,可以进行List、Set、Map集合的操作。

猜你喜欢

转载自blog.csdn.net/qq_34802416/article/details/79717452