泛型

为什么需要泛型

早期的Object类型可以接收任意的对象类型 但在实际使用中 会有类型转换的问题 存在隐患 所以

提供泛型解决这一问题

泛型:类型参数化 或者参数化类型 将类型作为参数传入

<任意的大写字母 可以有多个>

泛型的传入类型只能是 类类型

public class TypeDemo {
    public static void main(String[] args) {
        //没有定义类型 默认是Object
        ArrayList list=new ArrayList();
        list.add("a");
        list.add(1);
        list.add(false);

        for (int i = 0; i < list.size() ; i++) {
            //再具体使用时要向下转型
            Object obj=list.get(i);
            if (obj instanceof String){
                String s=(String) obj;
            }
            if (obj instanceof Integer){
                Integer s=(Integer) obj;
            }
            if (obj instanceof Boolean){
                Boolean s=(Boolean) obj;
            }
        }
        
  public class TypeDemo <T,E>{
    T name;
    E age;
    public  T test(E e){
        return null;
    }
   public static void main(String[] args) {
       TypeDemo<String,Integer> t=new TypeDemo<>();
        t.test(2);
   }
  }

集合的概念

集合 是一种容器

数组也是一个容器 但是长度一经定义不可改变并且只能存储同一种类型的数据

java为什么要提供许多的集合类在存储数据?

1.集合类的长度是可以改变的

2.不同的数据存储 操作方式不同

集合体系的概述

Collection 单列集合
List 可重复

ArrayList 底层数组实现的 查询快 增删慢 当数组扩容后没填满 空间浪费

创建之初 在底层创建一个默认的数组 当数组内容满了之后 继续添加时会扩容

LinkedList 底层是链表实现的 查询慢 增删块

查找时从第一个向后查找

增加删除元素是其他元素位置不动 只改变指针域的值

Vector:底层是数组实现 线程安全

ArrayList与LinkedList的区别

ArrayList:查找元素时候可以直接通过元素的下标进行索引,检索速度快。
若要在第i个位置插入元素时需要先找到第i个元素的位置,再将第i+1个元素及以后的元素全部向后移动一位,在插入第i个位置。
若要删除第i个位置上的元素,需要先找到的i个位置,删除该位置上的元素,在将第i+1位及以后的所有元素都向前移动一位。
因此对于ArrayList来说,
插入和删除元素的效率不如LikedList快。

LinkedList:在增删改较多的情况下使用LinkedList
LinkedList的底层实现是链表,链表有头结点,数据域和指针域三部分组成。
在插入元素时,只需要找到指定位置,将该位置元素的头指针与上一个元素断开,将该要插入的元素的头结点链接到上一个元素的尾结点处,
在将要插入的元素的尾结点链接到第i个元素的头结点上即可。对于删除操作是相反的,先断开第i个元素的头指针与尾指针,
在将i+1个位置上的元素与第i个位置上的元素链在一起即可。用LinkedList减少了元素前后移动所需耗费的时间。对于查找操作,
需要根据一定的算法从前向后或者从后向前进行遍历,速度较慢。

public class ArrayListDemo1 {
    /*
    List接口特点
      可以存储相同元素
      有序的 按照元素的插入顺序排列
     ArrayList 底层数组实现的 查询快  增删慢 当数组扩容后没填满 空间浪费
               创建之初 在底层创建一个默认的数组 当数组内容满了之后 继续添加时会扩容
    LinkedList 底层是链表实现的 查询慢 增删块
               查找时从第一个向后查找
               增加删除元素是其他元素位置不动 只改变指针域的值
    Vector
     */
    public static void main(String[] args) {
        ArrayList list=new ArrayList();
        /*
        调用默认无参的构造方法创建对象时并没有实际创建数组  第一次添加元素时创建 默认长度为10
         */
        ArrayList list1=new ArrayList(10);
        /*
        调用有参的构造方法 创建ArrayList对象时 创建一个指定长度的数组 this.elementDate=new Object[initialCapacity];
         */
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        list.add("f");
        list.add("g");
        list.add("d");
        list.add("i");
        list.add("j");
        list.add("k");//当数组满了之后 会自动扩容 容量为之前的1.5倍

        //list.remove(2);删除索引位置2的元素
        //System.out.println( list.remove("a"));//有a的话删除 返回true
        //list.isEmpty();//判断是否为空
        list.add(3,"a");//向指定位置添加元素
        //list.clear();//清空
        //System.out.println(list.get(2));//得到指定位置的元素
        System.out.println(list.indexOf("d"));//得到指定元素 的位置
//        System.out.println(list.lastIndexOf("a"));
        //System.out.println(list.set(4,"a"));//将指定位置元素修改为指定元素
      // List l= list.subList(3,6);//截取3-6位置的元素
        //System.out.println(l);
        System.out.println(list);

    }
Set 不可重复

HashSet 底层是hash表实现

package com.ff.javacollection.day1.day5;

import java.util.HashSet;

public class HashSetDemo {
    public static void main(String[] args) {
        /*
          set不能存储重复元素
          HashSet 无序存储(这里的无序指的是 添加元素的顺序)

          HashSet的底层是HashMap
          HashSet只是使用了HashMap的键的那一列
          是从HashMap扩展出来的一格单列存储的类

        第一次添加元素时 会在底层创建一个长度为16 的哈希表

        用内容的hash值 计算此元素在hash表中的位置
          HashMap的底层 链表+红黑树
          当链表长度大于8 链表转为红黑树
           hash表默认长度为16  当容量添加为长度的0.75时  会自动扩容 扩容为原来的两倍


         */
        HashSet set=new HashSet();
        set.add("a");
        set.add("i");
        set.add("c");
        set.add("p");
        set.add("z");
        set.add("重地");//通话 重地 hash值相同 内容不同
        set.add("通话");

         /*
        1.哈希结构底层是如何存储数据的
           哈希表:本质也是数组
        2.HashSet是如何去除重复元素的
         先用元素的hash值比较(速度快) 但是内容不同 hash值也可能一样
         hash相同时 在使用 equals方法 判断内容是否相同(安全可靠 效率低)
         */
        System.out.println(set);

    }
}

TreeSet 底层是红黑树实现

public class TreeSetDemo3 {
	
	 public static void main(String[] args) {
		/*
		  Set 不能存储重复元素

		  TreeSet 可以按照元素的自然顺序排序

		               底层是红黑树
		 */
		 TreeSet<String> tset = new TreeSet<String>();
		                 tset.add("b");
		                 tset.add("a");
		                 tset.add("d");
		                 tset.add("c");
		                 tset.add("x");

		 /*
		  * Set遍历方式
		  */
		                 
		    //tset.stream().forEach((a)->System.out.print(a));
		                 
		     /* for (String t : tset) {
				 System.out.println(t);
			  }*/ 
		                 
	          Iterator<String> it =  tset.iterator();
	          while(it.hasNext()){
	        	  String e = it.next();
	        	  System.out.println(e);
	          }
	 }

}
Map双列集合

HashMap

public static void main(String[] args) {
        /*
        map集合
           键  值  对存储
         HashMap键是无序的

         */
        HashMap hashMap=new HashMap();
        hashMap.put(1,"a");
        hashMap.put(1,"b");//如果有重复的键 后面的值会把前面的覆盖掉
        hashMap.put(4,"a");
        hashMap.put(3,"a");
        hashMap.put(2,"a");
        hashMap.put(null,"d");//可以存储一个键为null的元素
        hashMap.put(null,"e");
        System.out.println(hashMap);
        System.out.println(hashMap.containsValue("e"));
        System.out.println(hashMap.containsKey(3));
        hashMap.clear();
        System.out.println(hashMap.isEmpty());
        System.out.println(hashMap);


    }

TreeMap 键是按照自然顺序排列

HashTable

public static void main(String[] args) {
        TreeMap<Integer,String> treeMap=new TreeMap();//键是按照自然顺序排列
        treeMap.put(1,"a");
        treeMap.put(5,"a");
        treeMap.put(4,"a");
        treeMap.put(2,"a");
        treeMap.put(3,"a");
        treeMap.put(3,"d");//若键中有重复元素 后面的值会覆盖前面的值
        //treeMap.put(null,"d");
        /*
        键的类型如果是自己创建的类 要实现comparble 接口
        不允许存储键为null的
         */
        System.out.println(treeMap);



   //   Hashtable初始容量为11 0.75 线程安全 无序
        Hashtable <String,String>hashtable=new Hashtable();
        hashtable.put("c","a");
        hashtable.put("b","a");
        hashtable.put("a","a");
        hashtable.put("b","b");
        hashtable.put("3","a");
        hashtable.put("3","d");//若键中有重复元素 后面的值会覆盖前面的值
        //hashtable.put(null,"c");不允许存储键为null的
        System.out.println(hashtable);
    }