Java基础:单例/集合/集合排序

单例设计模式(Singleton Pattern)

  • 单例模式作用:

    保证类在内存中只有一个对象

  • 如何保证类在内存中只有一个对象呢?
    1. 控制类的创建,不让其他类来创建本类的对象。即私有化构造方法.
    2. 在本类中定义一个本类的对象。Singleton INSTANCE;
    3. 提供公共的访问方式。 public static Singleton getInstance(){return INSTANCE}
  • 饿汉式

    class Singleton {
        //1,私有构造函数
        private Singleton(){}
        //2,创建本类对象
        private static Singleton INSTANCE = new Singleton();
        //3,对外提供公共的访问方法
        public static Singleton getInstance() {
            return INSTANCE;
        }
    }
  • 懒汉式, 单例的延迟加载模式

    class Singleton {
        //1,私有构造函数
        private Singleton(){}
        //2,声明一个本类的引用
        private static Singleton INSTANCE;
        //3,对外提供公共的访问方法
        public static Singleton getInstance() {
            //线程不安全
            if(INSTANCE == null)
                INSTANCE = new Singleton();
            return INSTANCE;
        }
    }
  • 其他单例模式

    //final修饰
    class Singleton {
        //1,私有构造函数
        private Singleton(){}
        //2,声明一个本类的引用,对外提供公共的访问方法
        public static final Singleton INSTANCE = new Singleton();
    }
    
    //静态内部类
    class Singleton {
        private Singleton(){}
    
        private static class Create{
            private static Singleton INSTANCE = new Singleton();
        }
    
        public static Singleton getInstance(){
            return Create.INSTANCE;
        }
    
    //枚举
    enum  Singleton {
        INSTANCE
    }
    
    //线程安全懒汉式
    class Singleton {
        private Singleton() { }
        private static Singleton INSTANCE;
        public static Singleton getInstance() {
            //线程安全
            if (INSTANCE == null) {
                synchronized (Singleton.class) {
                    if (INSTANCE == null) {
                        INSTANCE = new Singleton();
                    }
                }
            }
            return INSTANCE;
        }
    }
  • 23种设计模式:
    1. 单例模式(Singleton Pattern)
    2. 工厂模式(Factory Pattern)
    3. 抽象工厂模式(Abstract Factory Pattern)
    4. 建造者模式(Builder Pattern)
    5. 原型模式(Prototype Pattern)
    6. 适配器模式(Adapter Pattern)
    7. 桥接模式(Bridge Pattern)
    8. 组合模式(Composite Pattern)
    9. 装饰器模式(Decorator Pattern)
    10. 外观模式(Facade Pattern)
    11. 享元模式(Flyweight Pattern)
    12. 代理模式(Proxy Pattern)
    13. 责任链模式(Chain of Responsibility Pattern)
    14. 命令模式(Command Pattern)
    15. 解释器模式(Interpreter Pattern)
    16. 迭代器模式(Iterator Pattern)
    17. 中介者模式(Mediator Pattern)
    18. 备忘录模式(Memento Pattern)
    19. 观察者模式(Observer Pattern)
    20. 状态模式(State Pattern)
    21. 策略模式(Strategy Pattern)
    22. 模板模式(Template Pattern)
    23. 访问者模式(Visitor Pattern)

集合Collection

  • 集合概述:
    • 数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,而集合长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少.
    • 子类: ArrayList/LinkedList/HashSet/TreeSet
  • 数组和集合的区别
    1. 数组既可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型(对象地址)
    2. 数组长度是固定的, 集合的长度的是可变的,可以根据元素的增加而增长
  • 集合集成关系
    集合体系图.jpg

  • 集合中的方法

        boolean add(E e)    //增加,添加成功返回true
        boolean remove(Object o) //移除
        void clear()    //清空
        boolean contains(Object o) //是否包含
        boolean isEmpty() //true为空
        int size()
        boolean addAll(Collection c)//true添加成功
        boolean removeAll(Collection c) //true移除成功
        boolean containsAll(Collection c) //是否包含
        boolean retainAll(Collection c) //取交集,返回值true表示值有变化,false则值没变化
        T[] toArray(T[] a); //集合转数组。数组转集合:Arrays.asList(T... arr);
        Iterator<E> iterator(); //用于集合遍历
  • 集合的遍历

    1. for/while循环遍历

      ArrayList<Person> list = new ArrayList<>();
      list.add(new Person("c", 5));
      list.add(new Person("a", 3));
      list.add(new Person("z", 54));
      for (int i = 0; i < list.size(); i++) {
          Person person = list.get(i);
      }
    2. 增强for循环

      for(元素数据类型 变量 : 数组或者Collection集合) {
          使用变量即可,该变量就是元素
      }
      
      //例子
      ArrayList<String> list = new ArrayList<>();
      list.add("zhang");
      list.add("san");
      list.add("lisi");
      for (String s : list) {
          System.out.println(s);
      }
    3. 迭代器Iterator
      boolean hasNext() //是否有下一个
      Object next() //返回下一个元素

      ArrayList<String> list = new ArrayList<>();
      list.add("张");
      list.add("三");
      list.add("李四");
      Iterator<String> it = list.iterator();
      while (it.hasNext()) {
          String next = it.next();
          System.out.println(next);
      }
    4. 并发修改异常ConcurrentModificationException

      ArrayList<String> list = new ArrayList<>();
      list.add("zhang");
      list.add("san");
      list.add("lisi");
      Iterator<String> it = list.iterator();
      while (it.hasNext()) {
          //用list的add/remove都会引起ConcurrentModificationException
          //list.remove("zhang"); 
          list.add("wang");
          String next = it.next();
          System.out.println(next);
      }
    5. 解决并发修改异常

      • 使用Iterator自带的remove方法,但没有add方法

        ArrayList<String> list = new ArrayList<>();
        list.add("zhang");
        list.add("san");
        list.add("lisi");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String next = it.next();
            if ("san".equals(next)) {
                it.remove();
            }
            System.out.println(next);
        }
      • List(子类ArrayList/LinkedList)特有的迭代器:ListIterator<T> lit = list.listIterator();

        ArrayList<String> list = new ArrayList<>();
        list.add("zhang");
        list.add("san");
        list.add("lisi");
        ListIterator<String> lit = list.listIterator();
        while (lit.hasNext()) {
            String next = lit.next();
            if ("san".equals(next)) {
                lit.remove();
            } else {
                lit.add("MySon");
            }
            System.out.println(next);
        }
        System.out.println(list);
  • List(子类ArrayList/LinkedList)集合特点

    1. 有索引index

          void add(int, E) //根据索引指定位置插入值
          E set(int, E)   //根据索引修改指定位置的值,返回被修改的值
          E get(int)  //根据索引找元素
          E remove(int) //移除指定索引的值, 返回被移除的值
          int indexOf(Object)//根据值返回索引
    2. 特有的迭代器:ListIterator<T> lit = list.listIterator();
  • TreeSet集合特点

    1. 自动排序
    2. 保存的对象要实现Comparable接口或TreeSet构造方法传入Comparator接口子类对象

      // 实现Comparable接口
      public class Person implements Comparable<Person> {
          private String name;
          private int age;
      
          public Person(String name, int age) {
              this.age = age;
              this.name = name;
          }
      
          @Override
          public int compareTo(Person person) {
              return 0;
          }
      }
      
      // TreeSet构造方法传入Comparator接口子类对象
      TreeSet<Person> set = new TreeSet<>(new Comparator<Person>() {
          @Override
          public int compare(Person person, Person t1) {
              return 0;
          }
      });
    3. 底层使用二叉树算法
    4. 数据唯一
    5. 不能存null
  • HashSet集合特点

    • 不可存重复数据,可存null
    • 没有固定顺序

双列集合Map

  • 概述

    • 一个Key对应一个Value
    • Key不可重复
    • 子类: HashMap/TreeMap
  • Map与Collection的区别

    • Map是双列的,Collection是单列的
    • Map的键唯一,Collection的子体系Set是唯一的
    • Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效
  • 方法

    • a:添加
      • V put(K key,V value): 增加或替换
        • 如果键是第一次存储,就直接存储元素,返回null
        • 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
    • b:删除
      • void clear():移除所有的键值对元素
      • V remove(Object key):根据键删除键值对,并把值返回
    • c:判断
      • boolean containsKey(Object key):判断集合是否包含指定的键
      • boolean containsValue(Object value):判断集合是否包含指定的值
      • boolean isEmpty():判断集合是否为空
    • d:获取
      • Set<Map.Entry<K,V>> entrySet(): 用于集合遍历
      • Set<K> keySet():获取集合中所有键的集合,用于集合遍历
      • V get(Object key):根据键获取值
      • Collection<V> values():获取集合中所有值的集合
      • int size():返回集合中的键值对的个数
  • Map集合遍历

    1. 根据键找值:Set<K> keySet()

      HashMap<String, Integer> hm = new HashMap<>();
      hm.put("张三", 23);
      hm.put("李四", 24);
      hm.put("王五", 25);
      hm.put("赵六", 26);
      
      /*Set<String> keySet = hm.keySet();         //获取集合中所有的键
      Iterator<String> it = keySet.iterator();    //获取迭代器
      while(it.hasNext()) {                       //判断单列集合中是否有元素
          String key = it.next();                 //获取集合中的每一个元素,其实就是双列集合中的键
          Integer value = hm.get(key);            //根据键获取值
          System.out.println(key + "=" + value);  //打印键值对
      }*/
      
      for(String key : hm.keySet()) {             //增强for循环迭代双列集合第一种方式
          System.out.println(key + "=" + hm.get(key));
      }
    2. 根据键值对对象找键和值:Set<Map.Entry<K,V>> entrySet()

      HashMap<String, Integer> hm = new HashMap<>();
      hm.put("张三", 23);
      hm.put("李四", 24);
      hm.put("王五", 25);
      hm.put("赵六", 26);
      
      /*Set<Map.Entry<String, Integer>> entrySet = hm.entrySet(); //获取所有的键值对象的集合
      Iterator<Entry<String, Integer>> it = entrySet.iterator();//获取迭代器
      while(it.hasNext()) {
          Entry<String, Integer> en = it.next();              //获取键值对对象
          String key = en.getKey();                               //根据键值对对象获取键
          Integer value = en.getValue();                          //根据键值对对象获取值
          System.out.println(key + "=" + value);
      }*/
      
      for(Entry<String,Integer> en : hm.entrySet()) {
          System.out.println(en.getKey() + "=" + en.getValue());
      }
  • HashMap与TreeMap比较 (参考资料链接)
    1. HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap是最好的选择。
    2. TreeMap取出来的是排序后的键值对。插入、删除需要维护平衡会牺牲一些效率。但如果要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
    3. HashMap存取没有顺序,TreeMap按key排序。

集合排序

  1. Collections工具类

    boolean  Collections.addAll(Collection c, T... elements); //添加数组,添加成功返回true
    void Collections.sort(List list);   //排序,需实现Comparable接口
    void Collections.sort(List list, Comparator c); //按Comparator条件排序
    T Collections.min(Collection coll); //返回最小值
    T Collections.min(Collection coll, Comparator comp);//按Comparator条件返回最小值
    T Collections.max(Collection coll); //返回最大值
    T Collections.max(Collection coll, Comparator comp);//按Comparator条件返回最大值
    void Collections.shuffle(List list);//打乱
    void Collections.reverse(List list);//反转
  2. 排序举例

    ArrayList<Integer> list = new ArrayList<>();
    list.add(4);
    list.add(10);
    list.add(5);
    list.add(2);
    list.add(44);
    Collections.sort(list, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            //返回int>=0则位置不变,int<0则交换位置
            return o1 - o2;
        }
    });
    
    System.out.println(list);

<完>

发布了10 篇原创文章 · 获赞 18 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yingchengyou/article/details/82657856
今日推荐