Java核心技术卷1扫盲笔记

转义序列\u

       注释中不要出现\u,因为Unicode转义序列会在解析代码之前得到处理。

       转义序列\u和其他转义序列不同,其他转义序列,如:\t,\n等只能出现在双引号之中,而\u可以出现在加引号的字符串外。


java中保留的关键字

       const和goto是java中保留的关键字。


jdk8新增的join方法

       public static String join(CharSequence delimiter, CharSequence... elements):delimiter表示分隔符,所有的字符串都实现了CharSequence,这个函数相当于返回一个字符串,这个字符串是根据传入可变字符串参数,每两个参数间用分隔符连接起来的。


类型转换精度问题

Alt

       其中蓝色线表示不会损失精度,而红色线表示会损失精度。

       三条红线的情况,可以看下图,下图展示了浮点型(float)数据在计算机中的存储

Alt
       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;
                }
            }
        }

       运行结果:
Alt


数组与多维数组

       以下初始化语句是正确的。

        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;
    }

Alt

       并不能达到交换对象的目的,这个方法只是交换了对象的拷贝,方法执行完之后,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());

Alt

       ③ 不能实例化参数化类型的数组(只能用集合),也不能实例化类型变量和泛型数组(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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章