本文作者阅读了《java编程思想》的前七章,并且在阅读过程中记录下了下面的知识点。
1、对象的复制相当于引用,例如直接使用b=a复制数组,对b的改变会直接对a产生影响。
2、静态方法只能调用类中的静态变量,可以通过类名.静态方法名进行调用。
3、递归方法:可以自己调用自己
4、String类的函数codePointAt:x.codePointAt(i)代表x的第i个字母对应的ASCII码
5、背包、队列、栈 : Item相当于一个泛型参数
1)背包:Bag<Item> add(Item item) isEmpty() size 不支持删除功能,迭代遍历时顺序任意
2 ) 队列:先进先出 Queue() enqueue(Item item) deequeue() isEmpty() size() push将新元素加入链表尾;pop将元素从表头取出
3 ) 栈:后进先出 Stack() push() pop() isEmpty() size() push将新元素加入链表头;pop将元素从表头取出;peek查看栈顶元素的操作,只返回栈顶元素值,不弹出元素
6、引用类型 vs 原始类型:原始类型都是小写字母,int/double/float/char等;引用类型首字母大写,Integer/Double/Float/Character。两者会自动进行转换,对应自动装箱/拆箱过程。
7、java不允许泛型数组:泛型是不可共变的(A是B的基类,A[]是B[]的基类);泛型在运行时是被擦除的,所以在编译时对类型进行强化。 泛型:单个变量泛型表示<T>,pair变量泛型表示<K,V>
8、Arrays.sort()
9、final: 常数,初始化后不能被改变,修饰的方法在子类中不能被重写 (防止子类修改它的含义,并保证不会被覆盖),修饰的类不能被继承,修饰的引用不能指向其他对象 (但对象本身可以修改); 也可以在定义时定义空白final (只声明变量但不赋予值),然后在初始化或者首次调用时赋值,这样保证了不同具体对象之间的灵活性。 同时,使用final方法也可以将其调用转化为内嵌调用,消除了方法调用的开销。类中所有private方法都隐式指定为final。
static: 为特定域分配单一存储空间,而不考虑需要创建多少对象或者不用创建对象;希望某个方法不与包含她的类的任何对象关联在一起,即使没有创建对象也能调用这个方法,修饰的属性初始化后可以改变,修饰的属性对象只有一个,和具体对象无关,不能使用this, super来调用,不可修饰局部变量,可将内部类声明为静态; 静态方法不得调用非静态方法;非静态方法可以调用静态方法。 静态初始化动作只执行一次。
static final: 初始化后不得修改,可以通过类名访问,方法不能重写,可在不new对象的情况下访问。 只有当final变量被设置为static才能在编译时知道其值 (被初始化了),否则只能在运行时才能知道 (例如一些final变量由随机数来赋值)。 static final类型额变量,其变量名全是大写,且每个单词之间由下划线隔开。
10、INSTANCE关键字:单例模式,用于处理比较大、复杂的类,只初始化一次得到一个对象。
11、new SparseVector(vectorLength, indices, values)创建稀疏向量,第一个参数代表原始向量维度,第二个参数代表所有有值的位置索引,第三个参数代表每个位置上的对应值。
12、将数据转化为spark格式:先使用sc.parallelize将数据转化为JavaRDD格式,再使用PairFunction转化为JavaPairRDD格式。可以调用saveAsObjectFile将其存储于HDFS上。
public JavaPairRDD<String, SparseVector> transformer(List<Tuple2<String,List<Integer>>> list, int vectorLength, JavaSparkContext sc){
List <Tuple2<String, SparseVector>> newList = new ArrayList<Tuple2<String, SparseVector>>();
JavaRDD<Tuple2<String, SparseVector>> tagJavaRDD = sc.parallelize(newList);
return tagJavaRDD.mapToPair(new tagRDD2PairRDD());
}
private static class tagRDD2PairRDD implements PairFunction<Tuple2<String, SparseVector>,String, SparseVector> {
@Override
public Tuple2<String, SparseVector> call(Tuple2<String, SparseVector> stringSparseVectorTuple2) throws Exception {
return new Tuple2<String, SparseVector>(stringSparseVectorTuple2._1,stringSparseVectorTuple2._2);
}
}
13、public:元素任何人都可用;private:除类型创建者和类型的内部方法之外的任何人都无法访问;protected:和private作用相当,差别在于继承的类可以访问protected而不能访问private;package:当其他类型都没有显式定义时就默认为package类型,类可以访问在同一个包中的其他类成员,但在包以外相当于private。
14、1byte=8bits int=32bits char=16bits short= 16bits long=64bits float=32bits double=64bits 每一种类型在任何机器上大小都是相同的。
15、作用域 (变量的生命周期) 由花括号位置决定。但是java对象的引用在作用域终点消失,但对象本身依然占据内存空间,这就需要垃圾回收器,从而自动检测对象来辨别哪些是不再会被引用的对象,消除了内存泄漏的问题。
16、类中两种类型:字段 (数据成员);方法(成员函数)。 变量只有作为类的成员时才会给定默认值,如果只是局部变量(并非某个类的字段)则会在编译时报错。
17、Random.nextInt(n)返回一个大于0小于n的随机整数。
18、float a = 1e-43f;其中最后的f不能遗漏,也不能改成d,因为这里需要的是float型而编译器通常将指数作为double处理。
double a=1e-43;不会出现问题。
19、for循环语句中可以使用逗号操作符,但被间隔的两个变量必须为同一个类型。
20、方法重载:方法名称相同,传入的参数列表不同。
21、当类没有定义构造器时,编译器会调用默认构造器;当类中含有带参或是不带参的构造器时,编译器就不会创建默认构造器。如果自己定义了带参构造器,在新建一个对象时再调用不带参的构造器时就会报错。
22、java会自动执行垃圾回收机制,回收不再能被访问到的内存空间。如果JVM并未面临内存耗尽的情形,不会执行垃圾回收以恢复内存。 可以使用System.gc()强制执行垃圾回收,这时如果被回收的类中定义了finalize()函数时,这个函数就会被自动执行。所以finalize()函数会在准备执行垃圾回收时被调用。
23、枚举类型: public enum ClassName {A,B,C,D}
24、如果有两个含有相同名称的类库以“*”的形式导入时,如果该类库没有被使用则不会报错;如果使用该类库,则编译器会报错,强制要求明确指明是哪一个类。例如package a和package b中都含有类C,则如果同时import a和import b,并且使用C c=new C()时就会报错,只能使用a.C c = new a.C()或者b.C c = new b.C()。
25、extends用于创建一个类的子类;implements用于实现接口。java中只能继承一个类,但能实现多个接口。
26、类之间有继承关系时,调用子类的构造函数,会自动从基类开始扩散。例如,B extends A, C extends B,那么调用构造函数C()时,会以A()--B()--C()的顺序进行构造。 其次,如果基类的构造函数中有参数,则需要在子类中显式地调用基类的构造函数,并进行传参。 而类的清理动作与继承顺序相反,需要先清理子类,再清理基类。
27、复用类:
1) 组合:在一个类中创建另一个类的对象;
2) 继承:在一个类中extends另一个类;
3) 代理:在一个类B中创建另一个类A的对象,并在其中调用A的一部分方法作为B的方法。
28、try-finally语句:try代表下面的块是保护区,需要被特殊处理;无论保护区的代码执行结果如何,保护区后面的finally语句总要被执行。
29、@override注解是为了防止用户在不想重载时而意外地进行了重载。例如,在继承的过程中,如果用户原本在子类中想要覆写一个方法,但没有注意变成了重载 (函数名相同,但参数列表不同),如果加上@override就会在编译时报错:method does not override a method from its superlass。
30、组合和继承的区别
组合:1) 是为了在新类中使用现有类中的方法而非接口,也就是说新类的用户只能看到新类中定义的接口,而看不到现有类中定义的接口,现有类被设置为private。2)易于用户理解新类的结构,这时就可以将成员对象设置为public。当用户了解到在组装一组部件时,端口会变得易于理解。
继承:使用现有类并开发它的一个特殊版本,现有类作为一个通用类,为了某种特殊需要而将其特殊化。
当表示“is-a”的关系时使用继承,使用“has-a”的关系时使用组合。
31、当有类B继承类A,并且A和B中都有static变量时,先从基类开始加载每个类的static变量,再从基类开始加载每个类中的普通变量初始化以及构造函数。
32、运行速度:StringBuilder > StringBuffer > String StringBuffer中很多方法带有synchronized关键字所以更适用于多线程。