//Builder Pattern public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate;
public static class Builder{ //Required parameters private final int servingSize; private final int servings;
//Optional parameters - initialized to default values private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize,int servings){ this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val){ calories = val; return this; } public Builder fat(int val){ fat = val; return this; } public Builder sodium(int val){ sodium = val; return this; } public Builder carbohydrate(int val){ carbohydrate = val; return this; } public NutritionFacts build(){ return new NutritionFacts(this); } } private NutritionFacts(Builder builder){ servings = builder.servings; servingSize = builder.servingSize; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; }
} //Builder Test public static void Test_NutritionFacts(){ NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35) .carbohydrate(27).build(); System.out.println(cocaCola.GetCalories()); System.out.println(cocaCola.GetServings()); System.out.println(cocaCola.GetServingSize()); };
//Singleton with static factory public class Elvis { Private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; }
//try-with-resources -the best way to close resources. static String firstLineOfFile(String path) throws IOException{ try(BufferedReader br = new BufferedReader( new FileReader(path))){ return br.readLine(); } }
//Class with a typical equals method public final class PhoneNumber { private final short areaCode, prefix,lineNum; public PhoneNumber(int areaCode, int prefix, int lineNum) { this.areaCode = rangeCheck(areaCode, 999, "area code"); this.prefix = rangeCheck(prefix, 999, "prefix"); this.lineNum = rangeCheck(lineNum, 999, "line num"); } private static short rangeCheck(int val, int max, String arg){ if(val < 0 || val > max){ throw new IllegalArgumentException(arg + ":" + val); return (short)val; }
//Wrapper class - uses composition in place of inheritance public class InstrumentedSet<E> extends ForwardingSet<E> { private int addCount = 0; public InstrumentedSet(Set<E> s){ super(s); } @Override public boolean add(E e){ addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c){ addCount += c.size(); return super.addAll(c); } public int getAddCount(){ return addCount; } }
//Reusable forwarding class public class ForwardingSet<E> implements Set<E> { private final Set<E> s; public ForwardingSet(Set<E> s){this.s = s;}
public void clear() {s.clear();} public boolean contains(Object o){return s.contains(o);} public boolean isEmpty() {return s.isEmpty();} public int size() {return s.size()} public Iterator<E> iterator() {return s.iterator();} public boolean add(E e) {return s.add(e);} public boolean remove(Object o) {return s.remove(o);} public boolean containsAll(Collection<?> c){ return s.containsAll(c);} public boolean addAll(Collection<? extends E> c){ return s.addAll(c);} public removeAll(Collection<?> c){return s.removeAll(c);} public retainAll(Collection<?> c){return s.retainAll(c);} public Object[] toArray() {return s.toArray();} public <T> T[] toArray(T[] a) {return s.toArray(a);} @Override public boolean equeals(Object o){return s.equals(o);} @Override public int hashCode() {return s.hashCode();} @Override public String toString() {return s.toString();} }
//Skeletal implementation class public abstract class AbstractMapEntry<K,V> implements Map.Entry<K,V>{ // Entries in a modifiable map must override this method @Override public V setValue(V value){ throw new UnsupportedOperationException(); } // Implements the general contract of Map.Entry.equals @Override public boolean equals(Object o){ if (o == this){ return true; } if(!(o instanceof Map.Entry)){ return false; } Map.Entry<?,?> e = (Map.Entry) o; return Objects.equals(e.getKey(), getKey()) && Objects.equals(e.getValue(), getValue()); }
//Implements the general contract of Map.Entry.hashCode @Override public int hashCode() { return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); }
//Typesafe heterogeneous container pattern - implementation public class Favorites { private Map<Class<?>, Object> favorites = new HashMap<>();
public <T> void putFavorite(Class<T> type, T instance){ favorites.put(Objects.requeireNonNull(type),instance); } public <T> T getFavorite(Class<T> type){ return type.cast(favorites.get(type)); } } //每个键都有一个不同的参数化类型,比如一个可以是Class<String>,下一个可以是Class<Integer>, 这就是异构。
//Enum type with data and behavior public enum Planet { MERCURY(3.302e+23, 2.439e6), VENUS (4.869e+24, 6.052e6), EARTH (5.975e+24, 6.378e6), MARS (6.419e+23), 3.393e6); private final double mass; // In kilograms private final double radius; // In meters private final double surfacegravity; // In m/s^2 // Universal gravitational constant in m^3 / kg s^2 private static final double G = 6.67300E-11; // Constructor Planet(double mass, double radius){ this.mass = mass; this.radius = radius; surfaceGravity = G * mass / (radius * radius); } public double mass() {return mass;} public double radius() {return radius;} public double surfaceGravity() {return surfaceGravity;} public double surfaceWeight(double mass){ return mass * surfaceGravity; // F = ma } } //每个枚举变量括号后面的数值就是传递给构造器的参数 public class WeightTable { public static void main(String[] args){ doulbe earthWeight = Double.parseDouble(args[0]); double mass = earthWeight / Planet.EARTH.surfaceGravity(); for(Planet p: Planet.values()){ System.out.printf("Weight on %s is %f%n", p, p.surfaceWeight(mass)); } } }
//defensive copy class public final class Period{ private final Date start; private final Date end; //defensive copies of parameters public Period(Date start, Date end){ this.start = new Date(start.getTime()); this.end = new Date(end.getTime());
if(this.start.compareTo(this.end)>0){ throw new IllegalArgumentException(this.start + " after " + this.end); } }
//defensive copies of internal fields public Date start(){ return new Date(start.getTime()); } public Date end(){ return new Date(end.getTime()); } }