Java笔记5(集合框架)

只是一些自己认为重点和易错点的笔记

集合框架相关笔记

  • 集合是对象的容器;
  • 集合:长度不固定,只可存储引用类型,可使用装箱存储基本类型;
  • 数组:长度固定,可存储基本类型引用类型

Collection集合(父接口)

  • Collection接口包含了List接口和set接口;

  • Collection接口中的方法:

    //创建Collection接口对象
            Collection col = new ArrayList();
    //1 增加元素
            col.add("苹果");
            col.add("橘子");
            col.add("香蕉");
            col.add("梨");
            col.add("橘子");
            System.out.println("数量为:" + col.size());
            System.out.println(col);
    
    //2 删除元素
            col.remove("橘子");
            //清空集合
            //col.clear();
            System.out.println("数量为:" + col.size());
            System.out.println(col);
    
    //3 遍历
            //3..1 增强for
            for (Object o : col) {
                System.out.print(o + " ");
            }
            System.out.println();
            System.out.println("----------");
            //3.2 迭代器iterator
            Iterator iter = col.iterator();
            while(iter.hasNext()){
                String next = (String)iter.next();
                System.out.print(next + " ");
                iter.remove();
            }
            System.out.println();
            System.out.println(col.size());
    		System.out.println();
            System.out.println("--------------");
    //4 判断
            System.out.println(col.contains("苹果"));
            System.out.println(col.isEmpty());
    
    数量为:5
    [苹果, 橘子, 香蕉, 梨, 橘子]
    数量为:4
    [苹果, 香蕉, 梨, 橘子]
    苹果 香蕉 梨 橘子 
    ----------
    苹果 香蕉 梨 橘子
    0
    --------------
    false
    true
    

1. List子接口

  • 有序,有下标,可重复(可用for循环)

    方法和Collection的方法类似,只是多了一些用法;

    List li = new ArrayList();
            li.add("小米");
            li.add("苹果");
            li.add(0,"华为");
            System.out.println(li.size());
            System.out.println(li.toString());
    //删除
    		// System.out.println("------用索引删除---------");
    		// li.remove(1);
    		// System.out.println(li);
    //获取
            System.out.println("------通过索引获取元素---------");
            System.out.println(li.get(1));
            System.out.println("------通过元素获取索引---------");
            System.out.println(li.indexOf("小米"));
    //遍历
            System.out.println("-------for遍历--------");
            for (int i = 0; i < li.size(); i++) {
                System.out.println(li.get(i));
            }
            //iterator迭代器
            System.out.println("======iterator迭代器========");
            Iterator iter = li.iterator();
            while(iter.hasNext()){
                System.out.println(iter.next());
        }
            System.out.println("--------listIterator可反向遍历--------");
            ListIterator listIter = li.listIterator();
            while(listIter.hasNext()){
                System.out.println(listIter.next());
            }
            System.out.println("---");
            while(listIter.hasPrevious()){
                System.out.println(listIter.previous());
            }
        }
    
    3
    [华为, 小米, 苹果]
    ------通过索引获取元素---------
    小米
    ------通过元素获取索引---------
    1
    -------for遍历--------
    华为
    小米
    苹果
    ======iterator迭代器========
    华为
    小米
    苹果
    --------listIterator可反向遍历--------
    华为
    小米
    苹果
    ---
    苹果
    小米
    华为
    

1.1 List接口实现类

  • 1、ArrayList类

    数组结构实现,查询快,增删慢,线程不安全;

    刚开始容量为0,当添加任意一个元素之后,容量就为10;

    每次扩容至原来的1.5倍。

  • 2、Vector类

    数组结构实现,查询快,增删慢,线程安全

    运行效率比Array稍低;

    可使用枚举器elements()方法遍历;

  • 3、LinkedList类

    双向链表结构实现,增删快,查询慢;

2、set子接口

  • 无序,无下标,元素不可重复;

  • 方法全部继承自Collection接口;

    Set<String> set = new HashSet<>();
    

2.1Set接口实现类

  • 1、HashSet类

    存储结构为hash表;

    存储过程:

    • 根据hashCode计算存储的位置,若为空直接存储,若不为空执行第二步;
    • 再根据equals方法,若返回true则认为重复,否则就形成链表
    • 可以重写hashCode方法,使存储的哈希值一样,再重写equals方法来比较存储的值是否相同。
    HashSet(Integer) hs = new HashSet<Integer>();
    p1 = new person("张三",22);
    p2 = new person("张三",22);
    //这样是不行的
    hs.add(p1);
    //这样是可以的
    hs.add(new person("张三",22))
    
  • 2、TreeSet类

    • 存储结构为红黑树;

    • 基于排序顺序实现元素不重复;

    • 实现SortedSet接口对集合元素进行排序;

    • 元素对象必须实现Comparable接口,指定排序规则;

    • 通过CompareTo方法确定元素是否重复;返回0为重复元素;

      //通过Comparator接口创建集合并指定规则
      public static void main(String[] args) {
              TreeSet<Person> treeSet = new TreeSet<>(new Comparator<Person>() {
                  @Override
                  public int compare(Person o1, Person o2) {
                      int n1 = o1.getAge()-o2.getAge();
                      int n2 = o2.getName().compareTo(o2.getName());
                      return n1==0?n2:n1;
                  }
              });
      

Map集合(父接口)

  • 存储任意键值对;

  • 键:无序,无下标,不重复;

    值:无序,无下标,可重复

    public static void main(String[] args) {
            //1、创建Map对象
            Map<String,String> map = new HashMap<>();
            //添加元素
            map.put("usa","美国");
            map.put("uk","英国");
            map.put("cn","中国");
            map.put("china","中国");
            System.out.println(map.size());
            System.out.println(map.toString());
    
            //2、删除
    //        map.remove("cn");
    ////        System.out.println(map.size());
    
            //3、遍历
            //3.1使用keySet()
            //Set<String> set = map.keySet();
            for (String s : map.keySet()) {
                //get(key),通过key来获取value
                System.out.println(s.toString() +"-------"+ map.get(s));
            }
            System.out.println("-------------------");
            //3.2使用entrySet()
    //        Set<Map.Entry<String,String>> entr = map.entrySet();
            for (Map.Entry<String, String> str : map.entrySet()) {
                System.out.println(str.getKey() + "-------" + str.getValue());
            }
            System.out.println("----------------");
            //4、判断
            System.out.println(map.containsKey("china"));
            System.out.println(map.containsValue("日本"));
    
    
        }
    
    4
    {usa=美国, china=中国, uk=英国, cn=中国}
    usa-------美国
    china-------中国
    uk-------英国
    cn-------中国
    -------------------
    usa-------美国
    china-------中国
    uk-------英国
    cn-------中国
    ----------------
    true
    false
    

Map实现类

1、hashMap类

  • 线程不安全,允许null作为key或value;

  • 默认构造初试容量为16;

  • 使用Key的hashCode和equals作为判断重复的依据;

  • 实例化hashSet实际上是new了一个hashMap;

    hashSet的add()方法用的是hashMap中的put方法中的value值;

    public static void main(String[] args) {
            //创建对象
            HashMap<Student,String> hm = new HashMap<Student,String>();
    
            Student s1 = new Student("张无忌",23);
            Student s2 = new Student("赵敏",22);
            Student s3 = new Student("小昭",21);
    
    
            hm.put(s1,"河南");
            hm.put(s2,"郑州");
            hm.put(s3,"南阳");
            //需要重写hash和equals方法下面个才不会被加入
            hm.put(new Student("张无忌",23),"河南");
    
            System.out.println(hm.size());
            System.out.println(hm.toString());
            //删除
    //        hm.remove(s1);
    
            //遍历
            //keySet
            for (Student stu : hm.keySet()) {
                System.out.println(stu.toString()+"----"+hm.get(stu));
            }
            //entrySet
            for (Map.Entry<Student,String> en : hm.entrySet()) {
                System.out.println(en.getValue() + en.getKey());
            }
        }
    
    
    总结:
        HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
        当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数。
        jdk1.8当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率
    	jdk1.8 当链表长度小于6时,调整成链表
        jdk1.8以前,链表时头插入,jdk1 .8以后时是尾插入
    

2、TreeMap类

  • 实现了SortedMap接口(Map接口的子接口)

  • 可以对key自动排序;

  • 使用的是红黑树,添加元素使用put(对象,“值”),需要实现Comparable接口,并根据需要重写Compare方法。

    也可以在创建TreeMap方法的时候使用定制比较器(Comparator)的方式;

Collections工具类

  • List<Integer> list = new ArrayList<>();
    list.add(10);
    list.add(20);
    list.add(30);
    //1、sort()
    //默认对集合元素进行从小到大排序
    Collections.sort(list);
    
    //2、binarySearch()
    //二分查找,需要先进行排序
    //找到返回值的位置,未找到返回负数
    Collections.binary(list,20);
    
    //3、copy()
    //需要保证拷贝到的集合大小和被拷贝的集合大小一样
    List<Integer> li = new List<>();
    for(int i; i<list.size(); i++){
        li.add(0);
    }
    Collections.copy(li,list);
    
    //4、reverse()
    //反转
    Collections.reverse(list);
    
    //5、shuffle()
    //打乱
    Collections.shuffle(list);
    
    
    
    
    //集合转数组
    Integer[] arr =list.toArray(new Integer[3])
        
    //数组转集合
    //这个集合是受限的,不能添加和删除元素
        **基本类型数组转集合,需要修改为包装类**
        String[] aa= {"zhangsan","lisi", "wangwu"}
        List list = Arrays.asList(aa);
    
    
    

泛型

  1. 本质是参数化类型,把类型作为参数传递;

  2. 泛型只能是引用类型

  3. 常见形式:泛型类,泛型方法,泛型接口;

  4. <T,...>,T为类型占位符,表示一中引用类型

    public class MyGeneric<T>{
        //创建泛型变量
        T t;
        //创建泛型方法
        public void show(T t){
            System.out.print(t);
        }
        //返回泛型
        public T getT(){
            return t;
        }
    }
    
    
    //测试类
    public class Test{
     	public static void main(String[] args){
            MyGeneric<Integer> it = new MyGeneric<Integer>();
            
            //方法的调用和普通对象的调用一样
            
        }   
    }
    
  5. 泛型接口

    public interface MyInterface<T>{
        String name = "张三";
        T show(T t);
    }
    
    
    //1、实现方法时直接定义数据类型
    public class MyImpl implement MyInterface<String>{
        //重写show方法;
        public String show(String t){
            System.out println(t);
            return t;
        }
    }
    
    //2/创建测试对象的时候定义数据类型
    public class MyImpl2<T> implement MyInterface<T>{
        //重写show方法;
        public T show(T t){
            System.out println(t);
            return t;
        }
    }
    
  6. 泛型方法

    • 需要写在返回值的前面
    public class MyGenericeMethod{
    
        public <T>void show(T t){
        System.out.print(t);
    	}
    
    	public <T>T show(T t){
        System.out.print(t);
        return t;
    	}
    }
    //调用方法时不用指定数据类型,会根据你传递的参数自动识别类型
    
  7. 泛型集合

    可以限制添加入集合元素的类型:

    ArrayList<String> li = new ArrayList<String>();
    
posted @ 2021-02-27 11:16  一个菜菜的boy  阅读(43)  评论(0)    收藏  举报