Java学习笔记
tags: note java writing 学习笔记
C++的还没写完,又开一坑,慢慢写
基本语法 (P32)
基本类型
- 前缀0b表示二进制
Double.POSITIVE_INFINITY
;Double.NEGATIVE_INFINITY
;Double.NaN
;(用Double.isNaN()
检测)- final 指示常量
Unicode (P34)
- 码点(code point): 一个编码表中的某个字符对应的代码值
- Unicode分为17个代码级别, 其中一个代码级别为基本的多语言级别, 码点从U+0000到U+FFFF, 由一个代码单元表示, 其余从U+100000到U+10FFFF, 由一对代码单元表示
- Unicode会再解析代码前进行处理, 注意注释中的’\u’
运算符 (P38)
- 使用
strctfp
关键字标记的方法使用严格的浮点运算来生成可再生的结果 floorMod()
: 得到非负余数- 移位运算
>>, <<, >>>
:>>
用符号位填充高位,>>>
用0填充高位 - 枚举类型:
enum Size {S, M, L};
String字符串 (P45)
String常用方法
charAt()
int compareTo()
boolean equals()
boolean equalsIgnoreCase()
int indexOf(String str, int fromIndex)
int indexOf(int cp, int fromIndex)
查找String replace(Strint / StringBuilder old, new)
String substring(int begin, int end)
toLowerCase() toUpperCase()
String join(CharSequence delimiter, CharSequence... elements)
StringBuilder常用方法 (P54)
length()
append(String str / char c)
setCharAt(int i, char c)
insert(int offset, String str / Char c)
delete(int startIndex, int endIndex)
String toString()
输入输出 (P55)
输入
Scanner类(java.util.Scanner):
- Scanner(InputStream in)
- String nextLine()
- String next()
: 下一个单词
- nextInt(), nextDouble()
- hasNext(), hasNextInt(), hasNextDouble()
输出格式化 (P58)
System.out.printf()
与C/C++类似
文件输入输出 (P61)
Scanner(File f / String data)
从文件 / 字符串中读取数据PrintWriter(String fileName)
将数据写入文件Path get(String pathname)
构造Path
public static void main(String[] args) throws IOException
{
Scanner in = new Scanner(Paths.get("c:\\my\\1.txt"), "UTF-8");
String s = in.nextLine();
System.out.println(s);
PrintWriter out = new PrintWriter("c:\\my\\2.txt", "UTF-8");
out.println(s);
out.close();
in.close();
}
流程控制 (P63)
与C/C++类似
带标签的break (P75)
break跳转到带标签的语句块末尾, 标签必须在语句块前面
大数值 (P76)
BigInteger和BigDecimal类:
- add(), subtract(), multiply(), divide(), mod(), compareTo()
- valueOf(long x, int s)
: 返回x或x^s^的大数
数组 (P79)
常用方法(P85):
- toString(), copyOf(type[] a, int s), copyOfRange(type[] a, int s, int e)
- sort(type[] a), int binarySearch(type[] a, type v), int binarySearch(type[] a, int s, int e, type v)(返回下标)
- fill(), equals()
- 都是static方法
对象与类 (P91)
对象构造 (P123)
- 只有在没有提供任何构造器的时候, 系统才会提供默认构造器
- 可以在类定义中, 直接将一个值赋给任何域, 也可以调用方法对域初始化, 在执行构造器之前, 先执行赋值操作
- 可以在构造器的第一个语句使用
this(...)
调用同一个类的另一个构造器 - 可以使用初始化块初始化数据域, 在一个类的声明中, 可以包含多个代码块, 只要构造类的对象, 这些块就会被执行(依照在类声明出现的次序)
- 对象析构, 为类添加finalize方法, 会在垃圾回收前调用. (P130)
包 (P131)
import
- 导入类:
import java.util.*;
,import java.util.Date;
- 导入静态方法, 静态域:
import static java.lang.System.*;
,import static java.lang.System.out;
- 将类放入包中:
package a.b.c;
, 文件要在与完整包名匹配的目录下(a\b\c) - 编译时编译文件(javac,
javac a\b\c\.java
), 解释器加载类(java a.b.c.
) - 包作用域, public可以被任意类使用, private只能被定义它们的类使用, 没有指定的话可以被同一个包的所有方法访问
文档注释 (P140)
类设计技巧 (P144)
- 保证数据私有
- 对数据初始化
- 不要使用过多基本类型(用其他的类代替多个相关基本类型, 更易于理解和修改)
- 不是所有的域都需要访问器和更改器
- 将职责过多的类分解
- 名称体现职责
- 优先使用不可变的类(如果多个线程同时更新一个变量, 就会发生不可预料的更改, 如果不修改而是返回一个状态已修改的新对象, 就可以安全地在多个线程中共享器对象)
继承 (P147)
超类和子类
extends
关键字extends
表示正在构造的新类派生于一个已存在的类
public class Manager extends Employee
{
//....
}
super
1. super
关键字指示编译器调用超类方法
super.getSalary();
2. 调用超类构造器(必须是子类构造器的第一条语句)
super(a, b, c);//必须是第一条语句
多态 (P154)
- 超类变量可以引用任意一个子类对象, 但只能调用超类中的方法
final类和方法 (P157)
- 不允许扩展的类被称为final类, 使用
final
修饰符表明这是个final类, 不允许定义子类
public final class Executiv extends Manager
{
//...
}
- 类中的方法也可以声明为final, 子类不能覆盖这个方法
- 将方法或类声明为final目的是确保它们不会在子类中改变语义
强制类型转换 (P158)
(Manager boss = (Manager) staff[0];
- 可以将子类的引用赋给一个超类变量, 但将一个超类引用赋给子类变量, 就必须进行类型转
- 如果无法进行类型转换, 会抛出
ClassCastException
异常 - 使用
instanceof
操作符检查是否能够成功转换
if(staff[1] instanceof Manager)
{
boss = (Manager) staff[1];
//...
}
抽象类 (P160)
- 使用
abstract
关键字将方法和设置为抽象的 - 抽象方法无需实现
- 包含一个或多个抽象方法的类必须被声明为抽象的
- 抽象类可以包含具体的方法和域
- 抽象类不能被实例化
- 可以定义一个抽象类的对象变量, 但是它只能引用抽象子类的对象
访问修饰符 (P165)
修饰符 | 可见性 |
---|---|
private | 仅对本类可见 |
public | 对所有类可见 |
protected | 对本包和所有子类可见 |
无修饰符 | 对本包可见 |
Object类 (P166)
- java所有类都是由Object类扩展而来
- 可以使用Object类型的变量引用任何类型的变量
- 数组也是Object的子类
equals方法
- equals方法用于检测一个对象是否等于另一个对象
- java语言规范要求equals方法具有以下特性:
- 自反性
- 对称性
- 传递性
- 一致性
- 对于任意非空引用x,
x.equals(null)
应返回false
- 当参数不属于同一个类时
- 如果子类拥有自己相等的概念, 使用
getClass
进行检测(不同子类不能相互比较) - 如果由超类决定相等概念, 那么使用
instanceof
进行检测(保证不同子类可以相互比较), 并将equals方法声明为final - 可以使用静态的
Arrays.equals
方法检测相应的数组元素是否相等 - 使用
@Override
对覆盖超类的方法进行标记:
@Override public boolean equals(Object other)
如果出现错误并且在定义一个新方法, 编译器就会报错
- 如果子类拥有自己相等的概念, 使用
编写一个equals方法 (P169)
1. 显式参数为Object otherObject
, 之后将其转换为一个交other的变量
2. 检测this和otherObject是否引用同一个变量
if(this == otherObject) return true;
计算这个等式比比较类中的域所付出的代价小得多
3. 检测otherObject是否为null, 如果为null, 返回false
4. 比较this和otherObject是否为同一个类
if(getClass() != otherObject.getClass())
return false;
如果所有子类拥有统一的语义, 使用instanceof检测
if(!(otherObject instanceof ClassName)) reutrn false;
5. 将otherObject转换为相应的类型变量
Class other = (ClassName) otherObject;
6. 对所有需要比较的域进行比较, 使用==比较基本类型域, 使用equals比较对象域
hashCode方法 (P170)
Equals
应该和hashCode
的定义一致:如果x.equals(y)
返回true
, 那么x.hashCode()
应该等于y.hashCode()
- 使用null安全的
Objects.hashCode
, 如果参数为null, 这个方法会返回0 - 使用静态方法
Integer.hashCode
,Double.hashCode
来避免创建基本类型的对象(也可以直接使用Objects.hashCode
) - 需要组合多个散列值时, 使用
objects.hash
并提供多个参数, 这个方法会对所有参数调用Objects.hashCode
并组合这些散列值 - 使用
Arrays.hashCode()
计算一个数组的散列值, 使用Objects.hashCode
会返回另一个不同的值, 这个值与对象存储地址有关 - 如果未定义
hashCode
方法, 默认方法会返回一个与对象存储地址有关的值
ArrayList (P178)
- 语法
ArrayList<ClassName> alc = new ArrayList<>();
ArrayList<E>(int)
: 用指定容量构造boolean add()
: 在尾端添加一个元素size()
ensureCapacity(int)
: 设置容量, 如果小于当前尺寸, 将不会改变trimToSize()
: 将数组列表容量削减到当前尺寸set(int index, E obj)
get(int index)
add(int index, E obj)
E remove(int index)
: 删除并返回index出元素E[] toArray(E[])
对象包装器与自动装箱 (P184)
- 所有基本类型都有一个与之对应的类(包装器)
- 编译器会自动装箱和拆箱, Integer对象和int值可以相互赋值
static int parseInt(String s, int radix)
: 返回s表示的整型值, radix表示几进制, 缺省为十进制static int valueOf(String s, int radix)
: 返回s表示的整型对象
参数数量可变的方法 (P187)
- 函数最后一个参数类型名后面加
...
, 表示可变参数数量:
public static double max(double... values)
{
//...
}
- 可以将一个数组传给可变参数方法的最后一个参数, 所以将已经存在的最后一个参数是数组的方法重新定义为可变参数的方法而不会破坏已存在的代码
public static void main(String... args)