Java

基础语法

List>数组

T[] array = (T[])list.toArray(new T[size]);

数组>List

List<T> list = Arrays.asList(array);

List<T>[]的创建

List<T> listArray = new List[length];

HashMap使用

//查找
map.containsKey(key);

//添加
map.put(key, value); //若第一次存,返回null;若非第一次存,用新值覆盖旧值,返回旧值

//获取
map.get(key);

//获取(若无key则返回默认value)
map.getOrDefault(key, defaultValue);

//遍历
for (Map.entry<K, V> entry : map.entrySet()) {
    entry.getKey();
    entry.getValue();
}

HashSet使用

//查找
set.contains(element);
//添加
map.add(element);
//遍历(foreach)
for (E e : set)
//遍历(迭代器)
Iterator<T> iter = set.iterator();
while (iter.hasNext()) {
    iter.next()
}
//交集
set1.retainAll(set2);
//并集
set1.addAll(set2);
//差集
set1.removeAll(set2);

PriorityQueue使用

PriorityQueue<T> pq = new PriorityQueue<>(new Comparator<T>(){
    public int compare(T first, T second) {
        return second - first; //大顶堆
    }
});

TreeMap按照value排序

Map<K, V> map = new HashMap<K, V>();
//向map放入数据...
TreeMap<K, V> treeMap = new TreeMap<K, V>(new ValueComparator(map));
treeMap.putAll(map);
//比较器定义
class ValueComparator implements Comparator<K> {
   Map<K, V> map;
 
   ValueComparator(Map<K, V> map) {
      this.map = map;
   }
 
   public int compare(K a, K b) {
      V valueA = map.get(a);
      V valueB = map.get(b);
      if (valueB >= valueA) return 1;
      else return -1;
   }
}

TreeMap获取最近的<=、>=、<、>的元素key

treeMap.ceilingKey(key); // >= key
treeMap.ceilingEntry(key);
treeMap.floorKey(key); // <= key
treeMap.higherKey(key); // > key
treeMap.lowerKey(key); // < key

TreeSet获取最近的<=、>=、<、>的元素值

treeSet.ceiling(val); // >= val
treeSet.floor(val); // <= val
treeSet.higher(val); // > val
treeSet.lower(val); // < val

移位运算

num >> 4   //右移:高位按符号位是0还是1补
num << 4   //左移:低位补0
num >>> 4  //无符号右移:高位一律补0

父类转为子类

//可强转
Father father = new Son();
Son son = (Son) father;

//不可强转
Father father = new Father();
Son son = (Son) father;

重写equals方法原则

public boolean equals(Object otherObject) {
    //比较地址
    if(this == otherObject) return true;
    //是否为null
    if(otherObject == null) return false;

    //比较类型
    if(this.getClass() != otherObject.getClass()) return false;

    //强制转换
    ClassName other = (ClassName) otherObject;

    //比较域
    return domain1.equals(other.domain1) 
        && domain2.equals(other.domain2) 
        && domain3 == other.domain3
        && ...
}

ArrayList容量操作

list.ensureCapacity(capacity); //预计最大容量
list.trimToSize(); //削减容量至当前尺寸

数组复制

System.arrayCopy(src, srcStartIndex, dest, destStartIndex, length);
dest = Arrays.copyOf(src, newLength);

for-each遍历字符串

for(char ch : string.toCharArray()){
   ...
}

List的更新方法

list.add(index, element); //向index处插入element元素
E oldElement = list.set(index, element); //用element替换index处的元素并返回旧元素

Calendar获取年/月/日

Date date = new Date(System.currentTimeMillis());
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.get(Calendar.DATE); //日
calendar.get(Calendar.MONTH); //月
calendar.get(Calendar.YEAR); //年

SimpleDateFormat格式化输出时间

SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.format(new Date());

比较数组元素是否相等

Arrays.equals(array1, array2);

上取整

Math.ceil(decimal);

四舍五入

Math.round(decimal);

char[]转String

String.valueOf(charArray);

Comparator比较器

Arrays.sort(array, new Comparator<T>() {
   public int compare(T t1, T t2) {
      return t1 - t2; //若t1 > t2: 升序;若t1 < t2: 降序
   }
});

反射

Class类获取

//方法1:通过业务实例
MyClass instance = new MyClass();
Class class = instance.getClass();

//方法2:通过静态类Class
Class class = Class.forName(className);

//方法3:通过业务类
Class class = MyClass.class;

类域分析

Field[] fields = class.getFields(); //超类及类的公有域
Field[] fields = class.getDeclaredFields(); //超类及类的所有域
Field   field  = class.getField(fieldName); //指定名字
Field   field  = class.getDeclaredField(fieldName);
int modifiers = field.getModifiers(); //域修饰符
field.setAccessible(true); //开放私有访问权限
Object value = field.get(instance); //获取instance.field的值

类构造器分析

Constructor[] constructors = class.getConstructors(); //超类及类的公有构造器
Constructor[] constructors = class.getDeclaredConstructors(); //超类及类的所有构造器
Constructor constructor = class.getConstructor(paramTypes...); //指定参数类型,避免重载
Constructor constructor = class.getDeclaredConstructor(paramTypes...);
constructor.getModifiers(); //构造器修饰符
Object instance = class.newInstance(); //构造class所指类的无参对象
Object instance = constructor.newInstance(params...); //构造class所指类的有参对象

类方法分析

Method[] methods= class.getMethods(); //超类及类的公有方法
Method[] methods = class.getDeclaredMethods(); //超类及类的所有方法
Method method = class.getMethod(methodName); //指定名字
Method method = class.getMethod(methodName, paramTypes...); //指定名字+参数类型,避免重载
method.getModifiers(); //方法修饰符
method.invoke(instance, params...); //调用方法

数组构造

Object array = Array.newInstance(componentType, length);

泛型

数组可自动协变(Array会记住实际元素类型)

Parent[] parents = new Child1[5];
parents[i] = new Child2(); //运行时这里会报ArrayStoreError

泛型不可自动协变,需用? extends或? super

MyClass<Father> objs = new MyClass<Child>(); //编译错误!
MyClass<? extends Father> objs = new MyClass<Child>(); //不能set因为形参类型是CAP#1,能get
MyClass<? super Child> objs = new MyClass<Father>(); //get后是Object类型,能任意set


零碎知识点

  1. 子类一定可以转为父类,但父类不一定可以转为子类,能否转换的根本是看最初实例化的时候是子类对象还是父类对象。
  2. 反射机制能在运行中分析类、在运行中查看对象(编写toString()供所有类使用)、实现数组的操作代码(arrayGrow()供所有数组使用)、动态生成对象并执行对象方法,总之能“看透”class。反射能避免硬编码,对设计通用框架能大大减少代码,但可读性也因此降低,不利于分析代码逻辑,更重要的是降低了程序性能,因为反射需要解析.class字节码,JVM无法对这些代码进行优化。
  3. MyClass[]可以转为Object[],但int[]不能转为Object[]。
  4. protected方法不可被异包的外部类访问,只能被同包的子类/外部类或异包的子类访问。
  5. 要实现深拷贝(即拷贝含有对象成员的对象),除要重写Object类的clone方法外,还要实现cloneable接口。
  6. 标识接口不含任何抽象方法,只作为标记使用,告诉JVM该类具备接口所标识的能力继而区别对待。
  7. 父类实现了某个接口的抽象方法,子类也会随之继承得到。
  8. Java只支持单继承,因而最多只能继承一个抽象类,若要继承多个,就需要使用接口了。
  9. 抽象类是对类根源的建模,而接口是对动作的建模。
  10. 抽象类中可以有抽象方法,也可有非抽象方法,
  11. abstract/interface和final是不能共存的。
  12. private不可修饰abstract类,但protected可以修饰abstract方法,但protected不可修饰interface方法。
  13. 子类属性若与父类属性同名,则以子类中的为准。若要访问父类中的那个,则加关键字super。
  14. comparable是内比较器,用compareTo(T t)实现this与t的比较;而comparator是外比较器,用compare(T t1, T t2)实现t1与t2的比较。
  15. T[]中的.clone()方法可以拷贝出一个新数组。

Leave a Comment.