【大数据开发必看】Java集合和泛型

第一章 集合

1.1 集合概述

  1. 定义:集合是java提供的一种容器,用来存储多个数据。
  2. 数组与集合的区别:
    1. 数组的长度是固定的,集合长度是可变的
    2. 数组中存储的是基本数据类型或者对象,集合存储的都是对象

1.2 集合框架

1.2.1 单列集合(Collection)
  1. 定义:单列集合类的根接口。
  2. 子接口:
    1. List子接口:
      1. 特点:元素有序可重复
      2. 实现类:
        1. ArrayList
        2. LinkedList
        3. Vector
    2. Set子接口:
      1. 特点:元素无序不可重复
      2. 实现类:
        1. TreeSet
        2. HashSet
          1. LinkedHashSet(元素有序)
1.2.2 双列集合(Map)
  1. 实现类:
    1. HashMap类
      1. LinkedHashMap子类
    2. Hashtable类

1.3 Collection集合

1.3.1 Collection接口
  1. 定义:由于它是一个接口,我们无法直接使用,需要间接使用Collection接口的实现类对象来操作集合。

  2. Collection对象创建:Collection接口有很多的实现类,例如ArrayList类。 (多态)

  3. 常用方法:

    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(): 把集合中的元素,存储到数组中
    
1.3.2 Iterator接口
  1. 定义:也叫迭代器,用于集合的遍历,由于它是一个接口,我们无法直接使用,需要间接使用Iterator接口的实现类对象来操作集合。

  2. Iterator对象创建:Collection接口中有一个方法叫做iterator(),返回的就是迭代器的实现类对象**(多态)**

  3. 迭代器使用步骤:

    1. 使用Collection中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收
      1. 获取实现类对象,并会把指针指向集合的-1索引
    2. 使用Iterator接口中的方法hasNext判断还有没有下一个元素
    3. 使用Iterator接口中的方法next取出集合中的下一个元素
      1. 第一步:取出下一个元素
      2. 第二步:指针后移一位

    例如:

    // 遍历集合中的元素
    Iterator<String> iter = coll.iterator();
    while(iter.hasNext()){
        System.out.println(iter.next());
    }
    
  4. 常用方法:

    boolean hasNext(): 判断集合中还有没有下一个元素
    E next(): 取出集合中的下一个元素
    
  5. 增强for:

    1. 定义:内部原理也是Iterator迭代器,专门用来遍历集合和数组

    2. 格式:

      for(元素的数据类型 变量 : 集合or数组){  }
      

    遍历共有三种方式:通过索引(有索引),通过Iterator,通过增强for

1.3.3 List子接口
  1. 三大特点:

    1. 它是一个元素存取有序的集合
    2. 它是一个带索引的集合
    3. 它可以包含重复的元素
  2. 常用方法:

    public void add(int index, E e): 添加元素
    public E get(int index): 获取元素
    public E remove(int index): 删除元素
    public E set(int index, E e): 设置元素(不可新增元素,只能修改元素)
    
1.3.3 ArrayList类
  1. 特点:底层是数组结构,因此增删慢,查找快

  2. 创建对象:

    1. 格式:ArrayList 对象名 = new ArrayList<>();
    2. 注意:
      1. 代表泛型,也就是装在集合当中的所有元素,全都是统一的什么类型
      2. 泛型只能是引用类型,不能是基本类型
      3. 对于ArrayList集合来说,直接打印得到的不是地址值,而是内容,如果内容是空,得到的是空的中括号:[]
  3. 常用方法:

    public boolean add(E e): 向集合当中添加元素,参数的类型和泛型一致
    public E get(int index): 从集合当中获取元素,参数是索引编号,返回值就是对应位置的元素
    public E remove(int index): 从集合当中删除元素,参数是索引编号,返回值就是被删除的元素
    public int size(): 获取集合的尺寸长度,返回值就是集合中包含的元素个数
    
1.3.4 LinkedList类
  1. 特点:底层是链表结构,因此增删快,查找慢

  2. 常用方法:

    public void addFirst(E e): 将指定元素插入到此列表的开头
    public void addLase(E e): 将指定元素插入到此列表的结尾
    public E getFirst(): 返回此列表的第一个元素
    public E getLast(): 返回此列表的最后一个元素
    public E removeFirst(): 移除并返回此列表的第一个元素
    public E removeLast(): 移除并返回此列表的最后一个元素
    public E pop(): 弹出一个元素    【等效于 removeFirst(E e)public void push(E e): 推入一个元素  【等效于 addFirst(E e)public boolean isEmpty(): 如果列表不包含元素,返回true
    
1.3.5 Vector类(了解)

​ 底层和ArrayList一样,也是数组结构

1.3.6 Set子接口
  1. 特点:
    1. 不允许存储重复的元素
    2. 没有索引,因此没有带索引的方法
  2. 常用方法:和Collection接口一致
1.3.7 HashSet类
  1. 特点:

    1. 它是一个元素存取无序集合
    2. 底层是一个哈希表结构,查询速度非常的快
  2. 常用方法:和Collection接口一致

  3. 哈希表:

    jdk1.8版本之前:哈希表=数组+链表

    jdk1.8版本之后:哈希表=数组+链表/红黑树

    注意:数组结构:把元素进行了分组(相同哈希值的元素是一组);链表/红黑树结构:把相同哈希值的元素链接到一起。如果链接到一起的数据超过了8个,会把链表转换为红黑树结构。

  4. 调用add方法的过程:

    集合在调用add方法的时候,会同时调用hashCode方法和equals方法,判断元素是否重复(如果两个元素的哈希值相同,就会调用equals方法,进而判断两个元素是否相同,相同就不会存储该元素)

总结:HashSet存储元素的时候,必须重写hashCode方法和equals方法。(Alt+Insert)

1.3.7.1 LinkedHashSet类
  1. 特点:底层是一个哈希表+链表:多了一条链表(用来记录元素的存储顺序),保证元素有序
1.3.8 可变参数
  1. 使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用

  2. 使用格式:定义方法时使用

    修饰符 返回值类型 方法名(数据类型…变量名){}

  3. 原理:底层是一个数组,根据传递参数的个数不同,会创建不同长度的数组,来存储这些参数,传递的参数个数可以是0个、1个…

  4. 注意事项:

    1. 一个方法的参数列表,只能有一个可变参数
    2. 如果方法的参数有多个,那么可变参数写在参数列表的末尾
  5. 终极写法:

    修饰符 返回值类型 方法名(Object… obj){}

1.4 Collections工具类

  1. 常用静态方法:

    public static <T> boolean addAll(Collection<T> list, T... elements): 往集合中添加一些元素
    public static void shuffle(List<?> list): 打乱集合顺序
    public static <T> void sort(List<T> list): 将集合中元素按照默认规则排序
    public static <T> void sort(List<T> list, Comparator<? super T>): 将集合中元素按照指定规则排序
    

    注意

    1. sort(List list)使用前提:被排序的集合里边存储的元素,必须实现Comparable接口,要重写接口中的compareTo方法(定义排序规则)

    2. Comparable接口的排序规则:【自己(this) 减 参数 表示升序】

    3. Comparator和Comparable的区别:

      1. Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口
      2. Comparator:相当于找一个第三方的裁判,比较两个
      // 按照指定规则排序----使用匿名对象和匿名内部类
      Collections.sort(list, new Comparator<Integer>() {
          @Override
          public int compare(Integer o1, Integer o2) {
              // return o1-o2; // 升序
              return o2-o1;  // 降序
          }
      });
      

1.5 Map集合

1.5.1 Map接口
  1. 特点:

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

    public V put(K key, V value): 把指定的键与指定的值添加到Map集合中(key不重复返回null,key重复会使用新的value替换旧的value,返回被替换的value)
    public V remove(Object key): 把指定的键所对应的的键值对元素在Map集合中删除(key存在返回被删除的value,key不存在返回null)
    public V get(Object key): 根据指定的键,在Map集合中获取对应的值
    boolean containsKey(Object key): 判断集合中是否包含指定的键
    public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中
    public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合
    
  3. Entry键值对对象:

    1. 定义:在Map接口中有一个内部接口Entry
    2. 作用:当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值的映射关系。
    3. 常用方法:【getKey() :获取key】 【getValue():获取value】
  4. 遍历:

    1. 利用keySet方法遍历的步骤:
      1. 获取集合中所有的key值,并存入Set集合中
      2. 遍历Set集合即可
    2. 利用entrySet方法遍历的步骤:
      1. 获取集合中所有的Entry对象,并存入Set集合中
      2. 遍历Set集合即可

注意:作为key的元素,必须重写hashCode方法和equals方法,以保证key不重复

1.5.2 HashMap实现类
  1. 特点:
    1. 底层是哈希表,查询速度特别快
    2. 它是一个无序集合
  2. 注意:
    1. HashMap存储自定义类型键值的时候,如果要保证key不重复,在自定义类中必须重写hashCode方法和equals方法。(快捷键生成)
    2. 它会自动按照key值进行排序(与哈希值有关)
1.5.2.1 LinkedHashMap子类
  1. 定义:extends HashMap
  2. 特点:
    1. 底层是哈希表+链表
    2. 它是一个有序集合
1.5.3 Hashtable实现类
  1. 特点:

    1. 底层也是一个哈希表,是一个线程安全的集合,是单线程的集合,速度慢
    2. 不可以存储null值、null键
    3. 它和Vector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了
    4. 它的子类Properties依然活跃在历史舞台
  2. Properties集合

    1. java.util.Properties:extends Hashtable<k,v> implements Map<k,v>
    2. 作用:Properties集合是一个唯一和IO流相结合的集合
      • 可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入硬盘中存储
        • void store(OutputStream out, String comments):不可以写入中文,comments注释
        • void store(Writer writer, String comments):可以写入中文
      • 可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
        • void load(InputStream input)
        • void load(Reader reader)
    3. 属性列表中每个键及其对应值都是一个字符串(默认)
    4. 操作字符串的特有方法.:
      1. Object setProperty(String key, String value):相当于Map集合中的put(key,value)
      2. String getProperty(String key):相当于Map集合中的get(key)
      3. Set<String> stringPropertyName():相当于Map集合中的keySet()(用于集合的遍历)
1.5.4 补充知识点
  1. JDK9的新特性:
    1. 概述:List接口、Set接口、Map接口:里边增加了一个静态的方法of,可以给集合一次性添加多个元素
    2. 格式:static List of (E… elements)
    3. 使用前提:当集合中存储的元素的个数已经确定了,不在改变时使用
    4. 注意:
      1. of方法只适用于List接口、Set接口、Map接口,不适用于接口的实现类
      2. of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法来添加元素
      3. Set接口和Map接口在调用of方法的时候,不能有重复的元素

第二章 泛型

2.1 泛型概述

​ 泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型。例如E、T

2.2 使用泛型的好处

  1. 创建集合对象,不使用泛型
    1. 好处:默认的类型是Object类型,可以存储任意类型的数据
    2. 弊端:不安全,易引发异常
  2. 创建集合对象,使用泛型
    1. 好处:避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型;把运行期异常提升到了编译期
    2. 弊端:泛型是什么类型,就只能存储什么类型的数据

2.3 泛型的定义和使用

  1. 定义和使用含有泛型的类:

    // 定义
    public class GenericClass<E> {
        private E name;  
        public E getName() {
            return name;
        }
        public void setName(E name) {
            this.name = name;
        }
    }
    // 使用
    public class Demo05Generic {
        public static void main(String[] args) {
            GenericClass<Integer> gc = new GenericClass<>();
            gc.setName(123);
            System.out.println(gc.getName());
        }
    }
    

    注意:创建集合对象的时候,就会确定泛型的数据类型

    1. 定义和使用含有泛型的方法:
    // 格式:修饰符 <泛型> 返回值类型 方法名(参数列表){}
    // 定义
    public class GenericMethod {
        public <M> void method01(M m){
            System.out.println(m);
        }
    }
    // 使用
    public class Demo06Generic {
        public static void main(String[] args) {
            GenericMethod gm = new GenericMethod();
            gm.method01("sunlei");
            gm.method01(10);    
        }
    }
    

    注意:在调用方法的时候确定泛型的数据类型。

    1. 定义和使用含有泛型的接口:

      1. 实现类的定义方式:
      2. 第一种实现方式:定义接口的实现类,实现接口,指定接口的泛型
      3. 第二种实现方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走
    // 接口定义
    public interface GenericInterface<T> {
        public abstract void method(T i);
    }
    // 实现类定义的两种方式
    // 第一种方式
    public class GenericInterfaceImpl implements GenericInterface<String>{
        @Override
        public void method(String i) {
            System.out.println(i); 
        }
    }	
    public static void main(String[] args) {
        GenericInterfaceImpl gii = new GenericInterfaceImpl();
        gii.method("sunlei");
    }
    // 第二种方式
    public class GenericInterfaceImpl<T> implements GenericInterface<T>{
        @Override
        public void method(T i) {
            System.out.println(i); 
        }
    }
    public static void main(String[] args) {
        GenericInterfaceImpl<String> gii = new GenericInterfaceImpl<>();
        gii.method("sunlei");
    }
    
    1. 泛型通配符

      1. 定义:不知道使用什么类型来接收的时候,此时可以使用?表示未知通配符

      2. 使用方式:不能创建对象使用,只能作为方法的参数使用

      ArrayList<?> list = new ArrayList<>();   // 不正确
      public static void printArray(ArrayList<?> list){} // 正确
      
      1. 高级使用之受限泛型(看懂代码即可)

      2. 泛型的上限限定:? extends E 代表使用的泛型只能是E类型的子类/本身

      3. 泛型的下限限定:? super E 代表使用的泛型只能是E类型的父类/本身

        // 此时的泛型,必须是Number类型或者Number类型的子类
        public static void printArray(ArrayList<? extends Number> list){}
        // 此时的泛型,必须是Number类型或者Number类型的父类
        public static void printArray(ArrayList<? super Number> list){}
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值