Java之集合

Java之集合,第1张

Java之集合 Java之集合 一、认识集合
  1. 集合也是一个对象,集合中不存储基本数据类型,只存储java中对象的内存地址,(基本类型数据存入集合,java后台会进行自动装箱)

  2. java中每种不同的集合都对应一个不同的数据结构,不同的数据结构,存储数据的方式不同。数据结构类型有:顺序表,栈,堆,队列,树,哈希表,链表等。。。例如:java中ArrayList类,Vector类底层为数组,linkedList 底层是链表(双向),TreeMap 底层是二叉树,HashMap类底层是哈希表

  3. 所有的集合类和集合接口都在java.util.*包下

  4. java中集合分为两大类:
    一类是单个方式存储元素,其超级父接口是java.util.Collection;
    一类是以键值对的方式存储元素,其超级父接口是java.util.Map;

  5. Java中常用集合的继承结构图


  1. 总结
    ArrayList:底层是数组
    linkedList:底层是双向链表
    Vector:底层是数组,线程安全的,效率低,使用少
    HashSet底层是HashMap,放到HashSet集合中的元素等同于放到了 HashSet集合的key部分
    TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到 TreeMap集合中的key部分,底层根据值的大小自动排序
    HashMap:底层是哈希表
    Hashtable:底层也是哈希表,只不过是线程安全的,效率低,使用较少
    TreeMap底层是二叉树
    List集合存储元素的特点:
    有序可重复
    有序:存进去的顺序和取出来的顺序相同,每一个元素都有下标。
    可重复:存进去1,可以再存储一个1
    Set/Map(Map中的key)集合存储元素的特点:
    无序不可重复
    无序:存进去的顺序和取出来的顺序不一定相同。另外Set集合中元素没有下标。
    不可重复:存进去1,不能再存储1了。
    SortedSet/SortedMap(SortedMap中的key)集合存储元素特点:
    首先是无序不可重复的,但是SortedSet集合中的元素是可排序的。
    无序:存进去的顺序和取出来的顺序不一定相同。另外Set集合中元素没有下标。
    不可重复:存进去1,不能再存储1了。
    可排序:可以按照大小顺序排列
    Map集合中的key就是一个Set集合。往Set集合中放数据,实际上是放到了Map集合中的key部分。注意:Map集合中的key不可重复但是value可以重复!!!
二、Collection接口: 1. Collection集合存储哪些元素

不使用“泛型”能存储Object的所有子类型
使用了“泛型”后,只能存储某个具体元素
注意:集合中不能直接存储基本数据类型和java对象,只存储java中对象的内存地址

2. Collection中的常用方法(公共方法,子类中都能用): boolean add(E e)向集合中添加指定的元素boolean addAll(Collection c)将指定集合中的所有元素添加到这个集合(可选 *** 作)。void clear()从这个集合中移除所有的元素(可选 *** 作)。boolean contains(Object o)根据equals()方法比较返回 true如果集合包含指定元素。boolean containsAll(Collection c)返回 true如果这个集合包含指定集合的所有元素。boolean isEmpty()返回 true如果集合不包含任何元素。Iterator iterator()返回此集合中的元素的迭代器。boolean remove(Object o)根据equals()方法比较,从这个集合中移除指定元素的一个实例,如果它是存在的(可选 *** 作)。boolean removeAll(Collection c)删除此集合中包含的所有元素(可选 *** 作)的所有元素(可选 *** 作)。boolean retainAll(Collection c)仅保留包含在指定集合中的这个集合中的元素(可选 *** 作)。int size()返回此集合中的元素的数目。Object[] toArray()返回包含此集合中所有元素的数组。 3. 迭代器Iterator

1.通过Collection接口中的iterator()方法获得迭代器对象
2.迭代器对象初始位置指向集合数据的前一个位置
3.迭代器的通用方法

  • next()移动迭代器对象使其指向集合的下一个元素并以Object对象返回该元素的值
  • hasNext(),判断是否还有下一个元素
  • remove(),底层调用equals方法进行比较,存在该对象则删除集合中的该元素
    注意:集合结构只要发生变化,迭代器就必须重新获取,否则会出现异常 在使用迭代器进行迭代时,应该使用迭代器中的remove()方法这样就能使得集合中的结构和迭代器指向的结构对应,而不是集合对象的remove()方法,因为集合对象在调用remove()方法时会改变集合中的结构,此时迭代器对象需要重新获取,否则会发生异常
4.Collection中的contains(Object o)方法

Collection中的contains(Object o)判断集合中是否包含集合该对象,底层调用equals方法比较,(存储的类型未重写equals()方法,则默认比较内存地址)(注意:如果是String类,则比较内容,因为String类的equals()方法被重写,比较的是内容),相同返回ture

三、List接口 1.List集合的特点

1.List接口继承Collection接口
2.List集合中的元素有序可重复,即元素有下标,存取顺序一致,可以存储相同的元素
3.集合元素下标从0开始

2.List集合中的常用方法

Collection接口中的方法都可以用

boolean add(int index ,Object element )向指定位置插入新元素booleanadd(Object element )向集合末尾中添加新元素int get(int index)得到集合中指定位置的元素int indexOf(Object element)获取指定对象第一次出现的索引int LastIndexOf(Object element)获取指定对象最后一次出现的索引void remove(int index )删除指定位置的元素set(int index ,Object element)修改指定位置的元素 3.List集合中的常用实现类 1.ArrayList集合

1.ArrayList类的无参构造方法默认容量为10(最初为0,当添加一个元素后初始化容量为10),
2.ArrayList(int initialCapacity) 构造一个长度为initialCapacity的集合
3.ArrayList(Collection c)通过实现了Collection接口的对象创建数组
3.如果add()添加的元素超过初始化容量,则底层自动将容量扩充为原来的1.5倍,扩容效率较低,优化策略,因为底层为数组,所以使用时建议预估计容量创建,
补充:数组扩容方法Arrays.copyOf(array,2*array.length);//第一个参数是待拷贝的数组对象,第二个是新数组的长度
4.底层是Object类数据
5.ArrayList 优点检索效率高
缺点,随机增删效率低(但向末尾添加元素效率高,不受影响
),无法存储大量数据,因为数组很难找到一大片连续的内存空间

2.linkList集合

linkList集合底层为双向链表:
优点:随机增删效率高,不涉及大量元素的位移 *** 作
缺点:查找的效率较低,每次查找元素都需要从表头开始遍历
特点:初始化没有任何元素,空间存储上内存地址不连续,适合存储数据量大的数据

3.Vector集合

特点:线程同步安全的,效率较低,底层为数组,无参构造初始化为10个元素,溢出扩容两倍
补充说明:将非线程安全的ArrayList变成线程安全的
(Collections工具类的静态方法sychronizedList(Collection obj)方法将集合obj变成线程安全的)

4.Set集合

Set集合特点:
Set集合是无序不可重复的,放在Set集合中的元素相当于放在了Map集合中的key部分

5.增强for(foreach)

JDK5.0之后推出的特性
语法:for(类型(和被遍历的集合或数组存储的元素类型一致) 变量名:数组或者集合){
}
优点,遍历方便
缺点,没有下标,不能删除集合元素
 1、对于数组,foreach 循环实际上还是用的普通的 for 循环
 2、对于集合,foreach 循环实际上是用的 iterator 迭代器迭代

四,Map集合

注意:Map和Collection没有关系

1.Map集合中的常用方法 V put(K key ,V value )向Map集合中添加键值对V get(Object key)通过key获取valuevoid clear()清空Map集合boolean containsKey(Object key)判断Map集合中是否含有某个keyboolean containsValue(Object value)判断Map集合中是否含有某个valueboolean isEmpty()判断Map集合中的元素是否全为空Set(K) keySet()获取Map集合中所有的keyV remove(Object key)移除Map集合中key元素的键值对default V replace(K key)根据给定的key移除对应的元素int size()返回键值对的数目Collection values()返回Map集合中所有的valueSet> entrySet()将Map集合转为Set集合

ps:containsX()这两个方法底层都是调用equals()方法进行比较,自定义类比较值需要重写,Entry是Map的静态内部类,

2.Map集合中的遍历

1.通过keySet()方法获取所有的key,然后遍历
(注意HashMap的key可以为空,且只有一个,value也可以为空)
2.通过 entrySet()方法转换成存储Map.Entry(本质上是Node节点组成的单链表)元素的Set集合,效率较高,通常使用该方法对Map集合进行遍历

Map集合遍历总结:

1、通过key集合访问,对Key敢兴趣,可以访问与key对应的Value值;

 for(String k:maps.keySet()){
            System.out.println(k+":"+maps.get(k));
        }
2、通过value集合访问,只对value值感兴趣,无法访问key值;

 for(String value:maps.values()){
            System.out.println(value);
        }
3、通过Entry集合访问,对Entry感兴趣,可以访问与key对应的Value值

 for(Entry entry:maps.entrySet()){
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
4、通过迭代Key集合访问Map集合,maps.keySet()返回的是一个Set集合,Set直接继承Collection,所以可以对其进行迭代。

Iterator iterator = maps.keySet().iterator();
        while(iterator.hasNext()){
            String key = iterator.next();
            System.out.println(key+":"+maps.get(key));
        }

5、通过迭代Values集合访问Map集合,maps.values()返回的是Collection,所以可以对其迭代。

Iterator iter= maps.values().iterator();
        while(iter.hasNext()){
            System.out.println(iter.next());
        }

6、通过迭代Entry集合访问Map集合,maps.entrySet()返回的是一个Set>,Set直接继承Collection,所以可以对其迭代。

Iterator> it = maps.entrySet().iterator();
        while(it.hasNext()){
            Entry entry = it.next();
            System.out.println(entry.getKey()+":"+entry.getValue());
        }



3.散列表/哈希表

哈希表是一个数组和单链表的结合体
数组:查询效率高,增删效率低
单向链表:随机增删效率高,查询方面效率低
哈希表将者两种数据结构组合在一起,充分发挥他们各自的优点(数组用于存储链表的表头节点,然后往对应的表头上加元素)

4. put方法添加元素原理:

第一步:将k v 键值对封装到Node对象中,
第二步:底层会调用hashCode()方法得到k对应的hash值,然后通过哈希算法,将hash值转换为对应数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上,如果对应的位置上有链表,此时会拿着k和链表上的每一个节点中的k进行equals()方法比较,如果都返回false则将该node添加到链表的末尾/或表头,如果有一个equals方法返回true则这个节点将会被覆盖。

5.get方法原理:

先调用k的hashCode()方法得出哈希值,通过哈希算法转换成数组的下标,通过数组下标快速定位到某个位置上,如果这个下标上面什么都没有,返回null,如果这个下标位置上有(单)链表,则k会与每个单链表上的key值进行equals()比较,如果所有的equals方法都返回false则get方法会返回null,只要有一个equals方法返回true,则此时这个节点的value就是我们要的value,则get方法就会返回这个value

6.HashMap类

1.放在HashMap集合中的key元素部分和放在HashSet元素部分需要同时重写hashCode()和equals()方法
2.HashMap集合初始化的数组容量是16,默认加载因子是0.75,即存储的数据达到数组容量的75%时会自动扩容为原来的2倍
注意:1.HashMap的初始化容量必须是2的倍数,这是官方推荐,目的是为了哈希表散列分布均匀,提高HashMap的存取效率。2.如果hashCode()方法和equals()方法使用IDEA生产时,需要同时生成
3.JDK8之后对HashMap集合的改进,加了门限值8,即:如果单向链表上的元素个数为8时,会自动把单向链表变成二叉树/红黑树,当元素个数又减小到6时,又会把树变成单向链表

7.Hashtable类

Hashtable的初始化容量为11,默认加载因子也为0.75,扩容方式为原容量的二倍再加1,注意:但是Hashtable的key和value 都不能为空,Hashtable集合是线程安全的

8.properties类

他是Hashtable的子类,它是属性类,它的key和value都是String类,是线程安全的,主要掌握put()和get()方法

9.TreeMap/TreeSet类

特点是无序不可重复,但里面的元素自动排序(数据结构为搜索二叉树),排序需要实现Comparable接口重写compareTo()或传递Comparator接口的比较器对象为集合的排序提供一个比较的依据,对于String和Integer等类型已经实现了Comparable接口的比较功能,我们只有要对我们存储在该集合中的自定义类型实现该接口,并重写compareTo()方法,可以不重写equals()方法。

10、集合比较规则的重写:

1.Comparable接口的compareTo()方法比较规则的重写方式
降序:k1.compareTo(k2),k1比k2大返回大于0的数,k1等于k2返回0,k1比k2小返回小于0的数,即:将列表中的元素作为参数和待加入的元素比较,返回小于0的数则放在二叉树的左边,大于0则放在二叉树右边,等于零则覆盖
2.Comparator接口,该接口需要实现compare()方法,它的两个参数分别是待插入节点和集合中的元素
3.TreeSet/TreeMap也可以****通过构造器传递该比较器实现类对象实现比较规则,通常用于比较规则进场发生改变的类,原理和compareTo()方法类似,在TreeSet集合底层,如果传递了Comparator比较器类对象,则优先使用Comparator比较器的比较规则

五.Collections工具类

常用方法:

static void copy(List dest, List src)将所有的元素从一个列表复制到另一个列表中。static >void sort(List list)指定列表为升序排序(集合中的元素排序需要实现Comparable接口)static void sort(List list, Comparator c)根据指定的比较器指定的顺序对指定的列表进行排序。static List synchronizedList(List list)返回由指定列表支持的同步(线程安全)列表。

创作不易,对您有所帮助的话可以点个赞支持下哦!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5693279.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存