一、集合
1.1 数组和集合的区别
数组:长度必须声明指定,不能更改,数组内的元素类型需要和数组声明的数据类型一致
集合:可以动态存储任意多个元素,增删元素有提供的方法,都实现了Collection或Map接口
1.2 数组动态扩容示例
//首先申明一个Persion类数组 长度为1
Persion[] persions = new Persion[1];
persions[0] = new Persion();
//扩容persions数组,并中添加一个persion元素
Persion[] persioncopy = new Persion[persions.length+1];
for(int i=0;i<=persions.length-1;i++){
persioncopy[i]=persions[i];
}
persioncopy[persions.length]=new Persion();
//或者
persions=Arrays.copyOf(persions,(persions.length+1)<<1);
1.3 常见集合关系继承实现类图
1.3.1 单列集合
指的是集合中存储的元素是单个的,Collection接口的实现子类都是单列集合
1.3.2 双列集合
指的是集合中存储的元素是以key/value的形式存储在集合中的,Map接口的实现子类都是双列集合
1.4 源码解析
-
ArrayList扩容实现
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
-
LinkedList核心代码
//元素实现 private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } //末尾添加元素 void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
-
Vector核心代码
/** ** initialCapacity 初始化数组长度 ** capacityIncrement 扩容时的增量长度 **/ public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } /** ** 遍历元素时生成一个新的Enumeration对象,通过count自增遍历数组内的元素 **/ public Enumeration<E> elements() { return new Enumeration<E>() { int count = 0; public boolean hasMoreElements() { return count < elementCount; } public E nextElement() { synchronized (Vector.this) { if (count < elementCount) { return elementData(count++); } } throw new NoSuchElementException("Vector Enumeration"); } }; }
Vector和ArrayList类似都是用一个数组去维护,扩容机制和ArrayList类型类似,当capacityIncrement=0时每次扩容为当前数组长度的2倍,否则扩容capacityIncrement长度
-
HashSet核心代码
//初始化一个Collection接口实现类的对象,该对像的值的4/3+1和16比较,取最大值初始化一个HashMap public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } /** ** initialCapacity 初始化大小 ** loadFactor 扩容时除的系数 **/ public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); }
-
TreeSet与TreeMap核心代码解析
/** **TreeSet实例化的过程中可以传递自定义的Comparator排序规则 **否则使用泛型的Comparator实现 **/ public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } /** ** TreeMap内部实现了一个二叉树 **/ static final class Entry<K,V> implements Map.Entry<K,V> { K key; V value; Entry<K,V> left; Entry<K,V> right; Entry<K,V> parent; boolean color = BLACK; /** * Make a new cell with given key, value, and parent, and with * {@code null} child links, and BLACK color. */ Entry(K key, V value, Entry<K,V> parent) { this.key = key; this.value = value; this.parent = parent; } } /** ** TreeSet内部维护了一个TreeMap实例 ** 下面是TreeMap添加元素的实现 **/ public V put(K key, V value) { Entry<K,V> t = root; //第一次添加 if (t == null) { compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null); size = 1; modCount++; return null; } int cmp; Entry<K,V> parent; // 初始化的比较器 Comparator<? super K> cpr = comparator; if (cpr != null) { do { parent = t; //使用比较器和key比较 cmp = cpr.compare(key, t.key); //key小于t.key时向左遍历 if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else //去重 return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } //给二叉树添加元素 Entry<K,V> e = new Entry<>(key, value, parent); if (cmp < 0) parent.left = e; else parent.right = e; //维持红黑树的平衡 fixAfterInsertion(e); size++; modCount++; return null; }
二、设计模式
1.1 前言
一个好的设计模式可以提高工作的效率,更加利于维护,可读性更高,下面就几种常用的设计模式进行学习
1.2 设计模式的种类
1.3 创建者模式
创建者模式指的就是构造对象的方法,下面主要说下单例模式和工厂模式
-
单例模式
public class Singleton { public static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if (instance == null) synchronized (Singleton.class) { instance = new Singleton(); } return instance; }
-
静态工厂方法模式
//接口 public interface Call { /** * 拨打电话 * @param telnumber */ Boolean makeACall(String telnumber); } //实现类1 public class FixedTelephone implements Call { @Override public Boolean makeACall(String telnumber) { if (telnumber.length() != 7) { System.out.println("请呼叫固话号码!"); return false; } System.out.println("呼~ 等待接通中:" + telnumber); return true; } } //实现类2 public class TelPhone implements Call{ @Override public Boolean makeACall(String telnumber) { if(telnumber.length()!=11){ System.out.println("请呼叫移动手机号码!"); return false; } System.out.println("为您呼叫:"+telnumber); return true; } } /** ** 静态工厂 **/ public class DataFactory { public static Call getTelPhone() { return new TelPhone(); } public static Call getFixedTelePhone() { return new FixedTelephone(); } public static void main(String[] args) { DataFactory.getTelPhone().makeACall("6233212"); } }
1.4 结构型模式
-
适配器模式
适配器模式的思想就是通过对接口的方法通过适配器去做适配以此达到兼容其他的接口或类
//原实现 public class Source { public String name = this.getClass().getSimpleName(); public void method1() { System.out.println(name+" runing method1"); } } //目标接口 public interface Targetabl{ void method1(); void method2(); } //适配器 public class BaseAdapter extends Source implements Targetabl{ @Override public void method2() { System.out.println("BaseAdapter runing method2"); } } public static void main(String[] args) { Targetabl targetabl = new BaseAdapter(); targetabl.method1(); targetabl.method2(); }
-
装饰者模式
装饰者模式就是装饰者类和被装饰者实现同一个接口,装饰者类获取接口实现类的对象,而后可以对接口的实现进行修改
//接口 public interface Sourceable { public void method(); } //被装饰者 public class Source implements Sourceable { @Override public void method() { System.out.println("the original method!"); } } //装饰者 public class Decorator implements Sourceable { //接口的实现对象 private Sourceable source; public Decorator(Sourceable source){ super(); this.source = source; } @Override public void method() { System.out.println("before decorator!"); source.method(); System.out.println("after decorator!"); } } public static void main(String[] args) { Sourceable source = new Source(); Sourceable obj = new Decorator(source); obj.method(); }
-
代理模式
让调用者只能通过代理去执行被代理对象的方法,调用者无法直接获取被代理对象和对该对象进行修改
//接口 public interface Sourceable { public void method(); } //被装饰者 public class Source implements Sourceable { @Override public void method() { System.out.println("the original method!"); } } //装饰者 public class Proxy implements Sourceable { //安全 private Sourceable source; public Proxy(){ this.source = new Source(); } @Override public void method() { System.out.println("before proxy!"); source.method(); System.out.println("after proxy!"); } } public static void main(String[] args) { Sourceable obj = new Decorator(); obj.method(); }
-
享元模式
不每次重复创建对象,而是在第一次初始化的时候创建多个对象放入池中,需要的时候取出,用完放回连接池中。
public class ConnectionPool { private Vector<Connection> pool; /*公有属性*/ private String url = "jdbc:mysql://localhost:3306/test"; private String username = "root"; private String password = "root"; private String driverClassName = "com.mysql.jdbc.Driver"; private int poolSize = 100; private static ConnectionPool instance = null; Connection conn = null; /*构造方法,做一些初始化工作*/ private ConnectionPool() { pool = new Vector<Connection>(poolSize); for (int i = 0; i < poolSize; i++) { try { Class.forName(driverClassName); conn = DriverManager.getConnection(url, username, password); pool.add(conn); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } /* 返回连接到连接池 */ public synchronized void release() { pool.add(conn); } /* 返回连接池中的一个数据库连接 */ public synchronized Connection getConnection() { if (pool.size() > 0) { Connection conn = pool.get(0); pool.remove(conn); return conn; } else { return null; } } }
1.5 行为型模型
-
策略模式
对接口分别实现,然后根据不同的需求使用对应的实现类
-
观察者模式
被观察者的改变会通知观察者
//首先定义一个更新通知接口 public interface Observer{ void update() } //定义观察者 public class Observer1 implements Observer{ public void update(){ sout("收到通知了") } } //定义一个被观察者接口 public interface Subject{ //注册观察者 void registerObserver(Observer observer); //取消绑定观察者 void unbindObserver(Observer observer); //通知所有的观察者*/ void notifyObservers(); } //定义一个实现了Subject的抽象类,让其他的要被注册的观察者继承它 public abstract class AbstractSubject implements Subject{ //使用Vector存储Observer队列,防止重复 private Vector<Observer> vector = new Vector<Observer>(); public void registerObserver(Observer observer){ vector.add(observer); } public void unbindObserver(Observer observer){ vertor.remove(observer); } //通知调用时触发每个Observer的update public void notifyObservers(){ Enumeration<Observer> elems=vector.elements(); while(elems.hasMoreElements()){ elems.nextElement().update(); } } } //定义一个类去继承AbstractSubject public class Person extends AbstractSubject { //为了方便定义在初始化的直接注册观察者 public Person(Observer... observers[]){ for(Observer observer : Observers) regiserObserver(observer); } private int age = 0; //每年年龄增长通知观察者 public void addage(){ age++; //发送通知 notifyObservers(); } }
-
责任链模式
责任链模式核心思想指把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。