Java集合


Java集合

Java集合

集合分为两类:

  • 以Collection及其子类为代表的的单个元素存储集合,称为Collection体系
  • 以Map及其子类为代表的的键值对存储集合,称为Map体系

特点:

  1. List:存储元素有序(输入顺序);存储元素可重复
  2. Set:存储元素无序(输入顺序);存储元素不可重复
  3. Map:以键值对为存储结构。

ArrayList:以数组为底层基础。

LinkedList:以链表为底层基础。

Vector:以数组为底层基础,线程安全(因为sygnoized关键字的存在)

HashSet:是以Hash表为底层基础,算法通过hashmap进行底层实现的,作为hashmap中的key存在。

SortedSet;TreeSet:是进行排序存在的(从小到大进行存储),以二叉树为底层基础

Hashmap:以哈希表为底层基础,通过key和value对应实现,key键不能重复。

HashTable:安全的,其他同hashmap。

TreeMap:是进行排序存在的(从小到大进行存储),以二叉树为底层基础,通过key和value对应实现,key键不能重复。

1. Collection

存储的元素类型

没有使用“泛型”之前,Collection中可以存储Object的所有子类型。

使用“泛型”之后,Collection中只能存储某个具体的类型。

集合中不能直接存储基本数据类型,需要转换为包装类型才可以。集合中存储的不是对象,而是java对象的内存地址。

Collection c = new ArrayList();没有使用泛型,能够存储Object所有子类型

Collection c = new ArrayList<>();使用泛型,只能存储Integer类型

常用方法

  • boolean add(Object e):向集合中添加元素
  • void clear():清除集合
  • boolean contains(Object e):判断集合中是否包含此元素,底层调用了equals方法(注意元素是否重写equals方法)
  • boolean isEmpty():判断集合是否为空
  • boolean remove(Object e):移除元素,底层调用的equals方法(注意元素是否重写equals方法)
  • int size():获得集合中元素个数
  • Object[] toArray():将集合转换为数组

2.迭代器Interator

所有的Collection都能够使用迭代器。

创建迭代器:

  • Interator i= c.Interator();
  • Interator i= c.Interator();

迭代器的常用方法:

  • hasNext():判断是否具有下一个元素
  • Next():获取下一个元素
  • Next

3.List集合

存储元素特点:有序且可重复

常用方法:

  • void add(int index,Object element):在指定位置添加元素
  • Object get(int index):获得指定位置的元素
  • int indexof(Object o):获得指定元素的首次出现的位置
  • int lastIndextOf(Object o):获得指定元素的最后一次出现的位置
  • Object remove(int index):移除指定位置的元素
  • Object set(int index,Object element):替换某个位置的元素

ArrayList

LinkedList

Vector

底层通过数组实现。线程安全的。

所有的Collection类可以通过方法Collections.synchronizedList()输出为安全的。

4.Set集合

HashSet

特点:

  • 存储时顺序和取出顺序不同
  • 不可重复
  • 放到HashSet集合中的元素实际上是放到HashMap集合的key部分。

TreeSet

特点:

  • 存储时顺序和取出顺序不同
  • 不可重复
  • 读取顺序从小到大。

5.Map集合

Map和Collection之间没有继承关系。Map集合是以key和value(即键值对)的方式存储数据的。

特点:

  1. key和value是引用类型
  2. key和value都是存储对象的内存地址。
  3. key起到主导作用,value是它附属的值。

常用方法:

  • V put(K key,V value):想Map集合中添加键值对
  • V get(Object key):通过key获取value
  • void clear():清空Map集合
  • boolean containsKey(Object key):判断Map中是否包含某个key
  • boolean containsValue(Object value):判断Map中是否包含某个value
  • boolean isEmpty():判断Map中的元素个数是否为0
  • Set keySet():获取所有的key
  • V remove(Object key):删除Map集合中的某个键值对
  • int size():获取map集合中的键值对的个数
  • Collection values():获取Map集合中所有的value,返回一个Collection
  • Set<Map.Entry<K,V>> entrySet():将所有的map集合转变为set集合。

遍历方法:

  1. keySet()方法获取map中所有的key生成set,通过遍历set,获得所有的value。
  2. entrySet()方法获取map中的Map.Entry生成set,通过遍历set,获取所有的value。

HashMap

特点:

1.HashMap集合底层是哈希表/散列表的数据结构

2.哈希表是一个数组和单向链表的结合体。

数组:在查询方面效率很高,增删效率很低。

单向链表:在增删方面效率较高,在查询方面效率很低。

哈希表将以上两种数据结构融合在一起,充分发挥各自的优点。

3.源代码:

public class HashMap<K,V>  {
    private static final long serialVersionUID = 362498820763181265L;
    //HashMap底层实际上就是一个数组(一维数组)。
    transient Node<K,V>[] table;
    //静态的内部类HashMap.Node
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;//哈希表(哈希表是key的hashCode()方法的执行结果,hash值通过哈希函数/算法,可获得哈希码)
        final K key;//存储到Map集合中的key
        V value;//存储到Map集合中的value
        Node<K,V> next;//下一个节点的内存地址
    } 

哈希表/散列表:一维数组,这个数组中每个元素是一个单向链表。

Java集合

​ 4.为什么哈希表查询和增删效率都高?

增删是在链表上进行的,查询只需要查询某一部分

​ 5.为什么要重写hashCode方法和equals方法?

hashCode方法返回每个node的hash值,确定元素的数组下标位置。equals方法是判断key内容是否相同,不是内存地址。

​ 6.我们需要保证哈希结构分布均匀,才能够发挥更好的性能,所以在重写hashCode方法时有一定的技巧。

7.HashMap集合的默认初始化容量是16,默认加载因子为0.75,就是HashMap底层数组的容量达到75%的时候,数组开始扩容。

HashMap集合初始化容量必须是2的倍数,这是官方推荐,这是因为达到散列均匀,为了能够提高HashMap集合的存取效率。

8.重写hashCode方法和equals方法

(1)向Map集合中存储,和Map集合中取,都是先调用key的hashCode方法,然后再调用equals 方法。

put(k,v),什么时候equals不会调用?

k.hashCode()方法返回哈希值。

哈希值经过哈希算法转换为数组下标

数组下标位置上如果是null,equals不需要执行。

拿get(k)举例,什么时候equals方法不会调用?

k.hashCode()方法返回哈希值

哈希值经过哈希算法转换为数组下标

数组下标位置上如果是null,equals不需要执行。

(2)注意:如果一个类的equals方法重写,那么hashCode方法必须重写。并且equals方法返回如果是true,hashCode()方法返回的值必须一样。equals方法返回true表示两个对象相同,在同一个单向链表上比较,那么对于同一个单向链表的结点来说,他们的哈希值都是相同的,所以hashCode()方法的返回值也应该相同。

9.Jdk8之后,哈希表单向链表中元素超过8之后,单向链表会变成红黑树。当红黑树上的结点小于6时,会重新将红黑树转为单向链表

结论:放在HashMap集合key部分的,以及放在HashSet集合中的元素,需要同时重写hashCode()方法和equals方法。

Hashtable

hashtable和hashmap基本上差不多,底层结构都是哈希表。

hashtable和hashmap之间的区别:

  • hashtable集合中key和value都不能为null;hashmap集合中key和value都可以为null;
  • hashtable集合中方法是synchronized的,线程安全的;而hashmap集合中方法是非synchronized的,线程不安全。
  • hashtable因为线程安全,所以效率低;hashmap效率较高。
  • hashtable初始容量为11,默认加载因子为0.75,扩容:newsize=oldsize2+1;hashmap初始容量为16,默认加载因子为0.75,扩容:newsize = oldsize2+1

Properties

Properties集合是一个Map集合,继承hashtable,Properties中的key和value都是String类型。

Properties被称为属性类对象。

常用方法:

  • setProperty(String key,String value):设置集合中的键值对
  • getProperty(String key):提取集合中的value

TreeMap

特点:

  1. TreeMap中的底层是一个二叉树。
  2. TreeMap集合中的元素是无序不重复的。但是会按照key的大小顺序自动排序,成为可排序集合。

对于自定义的类型,来说TreeMap是不能够进行自动排序的。如果我们需要排序,有两种方法:

方法一:

我们可以使自定义的类实现java.lang.Comparable接口。需要重写compareTo()方法,比较规则可以按照自己定的规则。

compareTo()返回值为int类型,结果大于0,在右子树找。结果小于0,在左子树找。

方法二

创建自定义对象的比较器xxxComparator,实现java.util.Comparator,要使用泛型结构Comparator,创建一个compare方法。

两种方法的选择:

如果不需要经常改变比较规则,就选择实现Comparable接口。

如果需要经常改变比较规则,就选择创建comparator。

6.集合工具类Collections

常用方法:

  • synchronizedList(List list):将list集合变为安全的
  • sort(List list):将list变成可排序的,但是需要元素类型继承Comparable接口。

List、Set和Map集合之间的转换方法

List转Set:new Set(list);

List转数组:list.toArray();

Set转List:new List(set)

Set转数组:set.toArray(arr);

Map转List:key:new List(map.keySet());value:new List(map.values())。

Map转Set:key:map.keySet();value:new Set(map.values())

数组转List:Arrays.asList(arr);

数组转Set:new Set(Arrays.asList(arr));

读取集合中的方法

  1. 迭代器方法
  2. 普通遍历
  3. foreach方法

原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/277410.html

(0)
上一篇 2022年7月27日
下一篇 2022年7月27日

相关推荐

发表回复

登录后才能评论