zoukankan      html  css  js  c++  java
  • 集合

    1.集合概述

    集合定义:

    • 集合:集合是java中提供的一种容器,可以用来存储多个数据。

    集合和数组的区别:

    • 数组的长度是固定的。集合的长度是可变的。
    • 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一
      致。在开发中一般当对象多的时候,使用集合进行存储。

    2.Collection

    JAVASE提供了满足各种需求的API ,在使用这些API前,先了解其继承与接口操作架构,才能了解何时采用哪个
    类,以及类之间如何彼此合作,从而达到灵活应用。

    • Collection :单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是
      java.util.List 和java.util.Set 其中,List的特点是元素有序、元素可重复。Set 的特点是元素无
      序,而且不可重复。List 接口的主要实现类有java. util.Arraylist和java.util. LinkedList,Set接口
      的主要实现类有java. util.HashSet和java. util. TreeSet。

    • Collection集合的常用功能

    Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可
    用于操作所有的单列集合。方法如下:

    public boolean add(E e):把给定的对象添加到当前集合中。
    public void clear():清空集合中所有的元素。
    public boolean remove(E e):把给定的对象在当前集合中删除。
    public boolean contains(E e):判断当前集合中是否包含给定的对象。
    public boolean isEmpty():判断当前集合是否为空。
    public int size():返回集合中元素的个数。
    public object[] toArray():把集合中的元素,存储到数组中。

    2.1 List集合

    java.util. List接口继承自collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对
    象称为List集合。在List集合 中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通
    过索引来访问集合中的指定元素。另外, List集合还有一个特点就是元素有序 ,即元素的存入顺序和取出顺序一
    致。

    List接口特点:

    1. 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。 那么集合中,元素的存储就是按照11.
      22、33的顺序完成的)。
    2. 它是一个带有索引的集合,通过索弓|就可以精确的操作集合中的元素(与数组的索引是一个道理)。
    3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

    List接口中常用方法:

    • public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
    • public E get(int index) :返回集合中指定位置的元素。
    • public E remove(int index) :移除列表中指定位置的元素,返回的是被移除的元素。
    • public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

    2.1.1 ArrayList集合

    java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能
    为查询数据、遍历数据,所以Arraylist是最常用的集合。

    构造方法:

    ArrayList​() 构造一个初始容量为十的空列表。

    常用方法:

    void add​(int index, E element) 在此列表中的指定位置插入指定的元素。  
    boolean add​(E e) 将指定的元素追加到此列表的末尾。  
    void clear​() 从列表中删除所有元素。  
    Object clone​() 返回此 ArrayList实例的浅拷贝。  
    boolean contains​(Object o) 如果此列表包含指定的元素,则返回 true 。  
    E get​(int index) 返回此列表中指定位置的元素。  
    boolean isEmpty​() 如果此列表不包含元素,则返回 true 。  
    Iterator<E> iterator​() 以正确的顺序返回该列表中的元素的迭代器。  
    E remove​(int index) 删除该列表中指定位置的元素。  
    E set​(int index, E element) 用指定的元素替换此列表中指定位置的元素。  
    int size​() 返回此列表中的元素数。  
    

    2.1.2 LinkedList集合

    java. util.Linkedlist集合implements List接口

    特点:

    1.底层是一个链表结构:查询慢,增删快
    2.里边包含了大量操作首尾元素的方法

    注意:使用L inkedList集合特有的方法,不能使用多态

    java. util.LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。

    LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解下

    实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。

    ●public void addFirst(E e) :将指定元素插入此列表的开头。
    ●public void addLast(E e) :将指定元素添加到此列表的结尾。
    ●public E getFirst() :返回此列表的第一个元素。
    ●public E getLast() :返回此列表的最后一个元素。
    ●public E removeFirst() :移除并返回此列表的第一个元素。
    ●public E removeLast() :移除并返回此列表的最后一个元素。
    ●public E pop() :从此列表所表示的堆栈处弹出一个元素。
    ●public void push(E e) :将元素推入此列表所表示的堆栈。
    ●public boolean isEmpty() :如果列表不包含元素,则返回true.
    

    2.2 Set集合

    java.util.set接口和java.util.List接口一样,同样继承自collection接口,它与collection接口中的方法
    基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同
    的是,Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

    Set接口的特点:

    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历

    tips:Set集合取出元素的方式可以采用 :迭代器、增强for。

    2.2.1 HashSet集合

    java.util.HashSet是Set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序
    不一致)。 java.util.HashSet 底层的实现其实是一个java.util.HashMap支持。

    HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一
    性的方式依赖于: hashCode 与equals方法。

    HashSet特点:
    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
    3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
    4.底层是一个哈希表结构(查询的速度非常的快)

    哈希值

    哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
    在Object类有一个方法,可以获取对象的哈希值
    int hashCode() 返回该对象的哈希码值。
    hashCode方法的源码:
    public native int hashCode();
    native:代表该方法调用的是本地操作系统的方法

    哈希表

    在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。
    但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中 ,哈
    希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找
    时间。

    Set集合存储元素不重复的原理

    HashSet存储自定义类型元素

    set集合报错元素唯一:
    存储的元素(String, Integer....student, Person...),必须重写hashCode方法和equals方法

    2.2.2 LinkedHashSet集合

    java. util.LinkedHashSet集合extends HashSet集合
    LinkedHashSet集合特点:
    底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序

    3.Collections集合工具类

    java.utils.Collections是集合工具类,用来对集合进行操作。

    常用功能:

    • public static boolean addAll(Collection C, T... elements) :往集合中添加一些元素。
    • public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
    • public static void sort(List list) }:将集合中元素按照默认规则排序。
    • public static void sort(List list , Comparator<? super T> ) :将集合中元素按照指定规则排序。
      注意:
      sort(list list)使用前提
      被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则
      Comparable接口的排序规则:
      自己(this)-参数:升序

    4.Map集合

    现实生活中,我们常会看到这样的一种集合: IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,
    这种一对应的关系 ,就叫做映射。Java提供了 专门的集合类用来存放这种对象关系的对象,即java.util.Map接
    口。javo.util.Map<k,v>集合

    Map集合的特点:

    1. Map集合是一个双列集合, 一个元素包含两个值(一个key, 一个value)
    2. Map集合中的元素, key和value的数据类型可以相同,也可以不同
    3. Map集合中的元素, key是不允许重复的,value是可以重复的
    4. Map集合中的元素, key和value是一一对应

    单列集合和双列集合的对比:

    • Collection中的集合,元素是孤立存在的(理解为单身) ,向集合中存储元素采用一个个元素的方式存储。
    • Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
    • Collection中的集合称为单列集合. Map中的集合称为双列集合.
    • 需要注意的是,Map中的集台个能包含重复的键,值可以重复;每个键只能对应一个值。

    Map集合常用的方法:

    1. public V put(K key, V value):把指定的键 与指定的值添加到Map集合中。
      返回值:v
      存储键值对的时候, key不重复,返回值V是null
      存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value值

    2. public V remove(0bject key): 把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值。
      返回值:V
      key存在, v返回被删除的值
      key不存在, v返回null

    3. public V get(Object key)根据指定的键,在Map集合中获取对应的值。
      返回值:
      key存在,返回对应的value值
      key不存在,返回null

    4. boolean containsKey(object key) 判断集合中是否包含指定的键。
      包含返回true,不包含返回false

    Map集合遍历键找值方式

    键找值方式:即通过元素中的键,获取键所对应的值

    分析步骤:

    1. 获取Map中所有的键,由于键是唯一的 ,所以返回一个Set集合存储所有的键。方法提示: keyset()
    2. 遍历键的Set集合,得到每一个键。
    3. 根据键,获取键所对应的值。方法提示: get(K key)

    Entry键值对对象

    我们已经知道,Map 中存放的是两种对象, 一种称为key(键) , 一种称为value(值) ,它们在在Map中是一对应关
    系,这一对对象又称做Map中的一个Entry(项)。Entry 将键值对的对应关系封装成了对象。即键值对对象,这
    样我们在遍历Map集合时,就可以从每一个键值对 ( Entry )对象中获取对应的键与对应的值。

    既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法:

    • public K getkey() :获取Entry对象中的键。
    • public V getValue() :获取Entry对象中的值。

    在Map集合中也提供了获取所有Entry对象的方法:

    • public Set<Map.Entry<K,V>> entryset() ;获取到Map集合中所有的键值对对象的集合(Set集合)。

    Map集合遍历的第二种方式:使用Entry对象遍历

    Map集合中的方法:

    Set<Map. Entry<K,V>> entrySet() 返回此映射中包含的映射关系的Set视图。

    实现步骤:

    1. 使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
    2. 遍历Set集合,获取每一个Entry对象
    3. 使用Entry对象中的方法getKey( )和getValue( )获取键与值

    HashMap存储自定义类型键值

    Map集合保证key是唯一的:

    作为key的元素,必须重写hoshCode方法和equals方法,以保证key唯一

    1. key:String类型
      String类重写hashCode方法和equals方法,可以保证key唯一
      value:Person类型
      value可以重复(同名同年龄的人视为同一个)

    2. key:Person类型
      Person类就必须重写hashCode方法和equals方法,以保证key唯一
      value:String类型
      可以重复

    4.1 Map集合常用子类---HashMap<K,V>

    java. util .HashMap<k, v>集合implements Map<k, v>接口

    • HashMap<K,V> :存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重
      复,需要重写键的hashCode(方法、equals()方法。

    HashMap集合的特点:

    1. HoshMap集合底层是哈希表:查询的速度特别的快
      JDK1. 8之前:数组+单向链表
      JDK1. 8之后:数组+单向链表/红黑树(链表的长度超过8) :提高查询的速度
    2. hashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致

    4.2 Map集合常用子类---LinkedHashMap<K,V>

    java. util. LinkedHashMap<k,v>集合extends HashMap<k, v>集合

    LinkedHashMap<K,V> : HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。
    通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复 ,需要重写键的
    hashCode(方法、equals()方法。

    LinkedHashMap的特点:

    1. LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
    2. LinkedHashMap集合是一个有序的集合 ,存储元素和职出元素的顺序是一致的

    Hashtable集合

    java. util . Hashtable<K, V>集合implements Map<K, V>接口

    Hashtable:底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
    HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快

    HashMap集合(之前学的所有的集合):可以存储null值, null键
    Hashtable集合,不能存储null值, null键

    Hashtable和Vector集合一样 ,在jdk1. 2版本之后被更先进的集合(HashMap, Arraylist)取代了
    Hashtable的子类Properties依然活跃在历史舞台
    Properties集合是一个唯一和I0流相结合的集合

    4.3 Properties集合

    概述

    java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties 方法就是返回一个Properties对象。

    Properties类

    构造方法

    • public Properties() :创建一个空的属性列表。

    基本的存储方法

    • public Object setProperty(String key, String value) : 保存一对属性。
    • public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
    • public Set<String> stringPropertyNames() :所有键的名称的集合。
    public class ProDemo {
        public static void main(String[] args) throws FileNotFoundException {
            // 创建属性集对象
            Properties properties = new Properties();
            // 添加键值对元素
            properties.setProperty("filename", "a.txt");
            properties.setProperty("length", "209385038");
            properties.setProperty("location", "D:\a.txt");
            // 打印属性集对象
            System.out.println(properties);
            // 通过键,获取属性值
            System.out.println(properties.getProperty("filename"));
            System.out.println(properties.getProperty("length"));
            System.out.println(properties.getProperty("location"));
    
            // 遍历属性集,获取所有键的集合
            Set<String> strings = properties.stringPropertyNames();
            // 打印键值对
            for (String key : strings ) {
              	System.out.println(key+" -- "+properties.getProperty(key));
            }
        }
    }
    输出结果:
    {filename=a.txt, length=209385038, location=D:a.txt}
    a.txt
    209385038
    D:a.txt
    filename -- a.txt
    length -- 209385038
    location -- D:a.txt
    

    与流相关的方法

    • public void load(InputStream inStream): 从字节输入流中读取键值对。

    参数中使用了字节输入流,通过流对象,可以关联到某文件上,这样就能够加载文本中的数据了。文本数据格式:

    filename=a.txt
    length=209385038
    location=D:a.txt
    

    加载代码演示:

    public class ProDemo2 {
        public static void main(String[] args) throws FileNotFoundException {
            // 创建属性集对象
            Properties pro = new Properties();
            // 加载文本中信息到属性集
            pro.load(new FileInputStream("read.txt"));
            // 遍历集合并打印
            Set<String> strings = pro.stringPropertyNames();
            for (String key : strings ) {
              	System.out.println(key+" -- "+pro.getProperty(key));
            }
         }
    }
    输出结果:
    filename -- a.txt
    length -- 209385038
    location -- D:a.txt
    

    小贴士:文本中的数据,必须是键值对形式,可以使用空格、等号、冒号等符号分隔。

    5.Iterator迭代器

    迭代的概念:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个
    元素取出来,继续在判断,如果还有就再取出出来。一直把集合 中的所有元素全部取出。这种取出方式专业术
    语称为迭代。

    获取迭代器的方法:

    • public Iterator iterator() ;获取集合对应的迭代器,用来遍历集合中的元素的。

    java. util. Iterator接口:迭代器(对集合进行遍历)
    有两个常用的方法:

    • boolean hasNext() 如果仍有元素可以迭代,则返回true.
      判断集合中还有没有下一个元素,有就返回true,没有就返回false
    • E next() 返回迭代的下一个元素。
      取出集合中的下一个元素

    Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
    Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
    Iterator iterator() 返回在此collection 的元素上进行迭代的迭代器。

    迭代器的使用步骤(重点):
    1.使用集合中的方法iterator( )获取迭代器的实现类对象,使用Iterator接口接收(多态)
    2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
    3.使用Iterator接口中的方法next取出集合中的下一个元素

    注意:
    Iterotor接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型

    6.增强for循环

    增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原
    理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

    for(元素的数据类型变量 : collection集合or数组){
    //写操作代码
    }
    

    它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。

    tips: 新for循环必须有被遍历的目标。目标只能是Collection或者是数组。 新式for仅仅作为遍历操作出现。

    7.Vector集合

    Vector类实现了可扩展的对象数组。 像数组一样,它包含可以使用整数索引访问的组件。 但是, Vector的大小可以根据需要增长或缩小,
    以适应在创建Vector之后添加和删除项目。

    从Java 2平台v1.2开始,该类改进了List接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Vector被同步。
    如果不需要线程安全的实现,建议使用ArrayList代替Vector 。

    8.可变参数

    可变参数:是JDK1.5之后出现的新特性

    • 使用前提:
      当方法的参数列表数据类型已经确定 ,但是参数的个数不确定,就可以使用可变参数。

    • 使用格式:定义方法时使用
      修饰符返回值类型方法名(数据类型.. .变量名){}

    • 可变参数的原理:
      可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
      传递的参数个数,可以是个(不传递),1,2...多个

    • 可变参数的注意事项
      1.一个方法的参数列表,只能有一个可变参数
      2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾

  • 相关阅读:
    Form组件
    LAMP+Varnish的实现
    缓存反向代理-Varnish
    CDN初识
    HTTP缓存初探
    Keepalived搭建主从架构、主主架构实例
    实现高可用-Keepalived
    nginx负载均衡实例
    lvs集群实现lvs-dr模型和lvs-nat模型
    LVS介绍
  • 原文地址:https://www.cnblogs.com/ITHSZ/p/13279426.html
Copyright © 2011-2022 走看看