转义序列\u
注释中不要出现\u,因为Unicode转义序列会在解析代码之前得到处理。
转义序列\u和其他转义序列不同,其他转义序列,如:\t,\n等只能出现在双引号之中,而\u可以出现在加引号的字符串外。
java中保留的关键字
const和goto是java中保留的关键字。
jdk8新增的join方法
public static String join(CharSequence delimiter, CharSequence... elements)
:delimiter表示分隔符,所有的字符串都实现了CharSequence,这个函数相当于返回一个字符串,这个字符串是根据传入可变字符串参数,每两个参数间用分隔符连接起来的。
类型转换精度问题
其中蓝色线表示不会损失精度,而红色线表示会损失精度。
三条红线的情况,可以看下图,下图展示了浮点型(float)数据在计算机中的存储。
float的存储结构是1个符号位,8个指数位,23个尾数。
switch case
在jdk7中加入了字符串面量。
跳到指定块的方法
hello:
if (x > 0) {
break hello;
}
label:
while (true) {
System.out.println("第一层循环...");
while (true) {
System.out.println("第二层循环...");
while (true) {
System.out.println("第三层循环...");
if (x > 0)
break label;
}
}
}
运行结果:
数组与多维数组
以下初始化语句是正确的。
int length = 8;
int[] b = new int[length];
输出一维数组用Arrays.toString
,输出高维数组用Arrays.deepToString
。
for (int i = 0; i < b.length; i++)
b[i] = i;
System.out.println(Arrays.toString(b));
int[][] x = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
System.out.println(Arrays.deepToString(x));
基于类的访问权限
Employee类的方法可以访问Employee类的任何一个对象的私有域。
class Employee {
...
private String name;
...
public boolean equals(Employee other) {
return name.equals(other.name);
}
}
final关键字
1、final用于修饰基本数据类型,表示数据不可再改变。
2、final用于修饰引用数据类型,变量中的对象引用不会再指向其他对象。
java方法参数的绑定规则
java总是采用按值调用的,即方法得到的是所有参数指的一个拷贝。只不过如果参数是引用对象的话,拷贝的变量和原变量指向的是一块内存空间。
分析下面代码:
public static void main(String[] args) {
Employee a = new Employee("小王", 10000);
Employee b = new Employee("小李", 13000);
System.out.println("before do swap... a=" + a + ", b=" + b);
swap(a, b);
System.out.println("after do swap... a=" + a + ", b=" + b);
}
private static void swap(Employee e1, Employee e2) {
Employee t = e1;
e1 = e2;
e2 = t;
}
并不能达到交换对象的目的,这个方法只是交换了对象的拷贝,方法执行完之后,e1和e2会被JVM回收,原来调用方法的a、b对象没有改变他们所指向的内存空间。
方法重载
必须是参数类型或者参数数量不同,返回值类型不作数。
静态导入
可以导入到方法级别。如:import static java.lang.Math.abs;
。
方法调用的底层
方法调用分为静态绑定和动态绑定。
1、静态绑定:private、static、final
2、动态绑定:JVM预先为每个类创建一个方法表(method table)。
访问修饰符
1、对本类可见:private。
2、对本包和所有子类可见:protected。
3、对所有类可见:public。
4、对本包可见:默认(缺省)。
Integer包装类的API
将Integer类型转换为String类型,将i转换为radix的进制,最后以String返回:String toString(int i, int radix);
。
将String类型转换为Integer类型,radix指明字符串s所表示的进制数,将其转为Integer返回:Integer parseInt(String s, int radix);
。
接口中方法的默认实现
接口中的变量默认都是:public static final
。
接口方法中用default声明后即可给出默认实现,如:
public interface Collection {
int size();
default boolean isEmpty() {
return size() == 0;
}
}
Objects.equals方法
Objects.equals(Object obj1, Object o2):
1、两个参数都为null,返回true。
2、其中一个参数为null,返回false。
3、两个参数都不为null,调用objq.equals(obj2)。
深拷贝和浅拷贝
本质都是重新new了一块堆空间。不过两者也有以下区别:
浅拷贝:引用类型只是复制引用。
深拷贝:所有属性都复制独立一份。
重写equals的技巧
equals为true的两个对象,哈希码必须相同。
待定。
lambda表达式
可以将函数式接口或匿名内部类简化。
List<String> list = new LinkedList<>();
list.add("123");
list.add("234");
list.add("345");
list.forEach(string -> {
System.out.println(string);
});
泛型
1、类泛型
class Fanxing<T>
,注:尖括号中使用extends
关键字来对T做限制(不管是接口还是类都是extends),如果有多个限制,中间用&
来分隔,而且如果有继承的类必须放在第一个位置,而且继承类的数量也只能有一个。
2、方法泛型
public static <T> void hello(T t)
,泛型参数放在修饰符后面,返回值类型的前面。
3、泛型机制
“伪泛型”,编译阶段会进行所谓的”类型擦除“,将尖括号中的内容都替换为具体的类型。
如果类型擦除之后出现下面的代码,则会调用桥接方法:
public Integer info(Integer i) {
return i;
}
public volatile Object info(Object o) {
return info((Integer)o);
}
4、泛型注意点
① 不能用基本类型实例化类型参数。
② 运行时查询只查原始类型,如:
FanXing<Employee> fanXing1 = new FanXing<>();
FanXing<Manager> fanXing2 = new FanXing<>();
System.out.println("FanXing1: " + fanXing1.getClass() + " , FanXing2: " + fanXing2.getClass());
System.out.println(fanXing1.getClass() == fanXing2.getClass());
③ 不能实例化参数化类型的数组(只能用集合),也不能实例化类型变量和泛型数组(new出Object的数组之后强转)。
实例化的时候重写类的部分方法
新知识!
Map<String, String> cache = new LinkedHashMap<String, String>(128, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > 100;
}
};
相当于只是将某个类中看的不爽的方法重写了,应该还是框架和jdk里面用的多(必须对该类非常熟悉,否则慎用),自己写的类玩这种骚操作就离谱。
Map最快的遍历方法
map.forEach((k, v) -> {
System.out.println("key: " + k + " value: " + v);
});
迭代器
1、ListIterator API:
在当前迭代器所在位置前添加元素:void add(E e);
。
替换当前迭代器所在位置的元素:void set(E e);
。
boolean hasNext();
。
返回当前迭代器所在位置的元素,并将迭代器往后挪一个位置:E next();
。
得到当前迭代器所在位置的索引:int nextIndex();
。
boolean hasPrevious();
(以下都同next部分)。
E previous();
。
int previousIndex();
。
2、Iterator API:同next部分。
优先队列
Queue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1; //增减排序
}
});
遍历要想下面这样,而不能直接输出queue。
while (!queue.isEmpty()) {
System.out.print(queue.poll() + " ");
}
位集的使用
位集可以用来替代布尔数组。
初始化位集,初始状态都为false:BitSet set = new BitSet(100);
将标记位置置为true:void set(int index);
将标记位置置为false:void clear(int index);
获得标记位:boolean get(int index);
Collection的一些API
计算集合中的最大值:public static max(Collecton<? extends Comparable> c);
计算集合中的最小值:public static min(Collecton<? extends Comparable> c);
归并排序(稳定):public static sort(List<?> l, Comparator<?> cmp);
List接口的求交集方法
boolean retainAll(Collection<?> c);