此笔记是在学习《Java语言程序设计:基础篇》所记录下的一些遗忘点。
所记录的内容基本来自书上。
int a = Integer.parseInt(String) //将数字字符串转换为整数
double d=Double.parseDouble(String) //将数字字符串转换为浮点数
System.out.println("count is %d and amount is %f",count,amount)
//%d替换为count整数,%f替换为amount浮点数
%b 布尔值
%c 字符
%e 科学记数法形式的数
%s 字符串
%10.2f 宽度至少为10,不够数字前面加空格,右对齐,保留两位小数
%-10.2f 同上,不过左对齐
Math.min()
Math.max()
Math.abs()
Math.random()方法生成大于等于0.0且小于1.0的double型随机数
Math.random() * 10 //返回0到9的随机数
(int) (Math.random() * 10) //返回0到9的随机整数
double [] array = new double[number]
double [] array = {value1,value2,.....}
new double[]{value1,value2,.....}
array.length //数组容量大小
for(double u : array){ //用变量u遍历整个数组, u必须为array中元素相同的数据类型
System.out.println(u);
}
两个数组list1,list2
若list2=list1,list1将数组引用赋给list2,list2也指向list1的数组,即两者指向同一个内存数组。
独立内存空间的复制数组有三种方法:
使用循环语句逐个地复制数组的元素。
使用System类的静态方法arraycopy。
arraycopy(源数组,源数组的起始位置(从0开始) y,目标数组,目标数组的起始位置(从0开始) k,复制个数n):从源数组第有y+1个元素开始复制到目标数组的第k+1个位置,复制n个元素。
注:arraycopy方法没有给目标数组分配内存空间,复制前必须创建目标数组以及内存空间。复制完成后两个数组具有相同的内容,但占有独立的内存空间。
使用clone方法复制数组。
可以把类型相同但个数可变的参数传递给方法。该参数叫可变长参数,声明如下:
public static void printMax(double… numbers)
**Java将可变长参数当做数组对待。**可将一个数组或可变的参数个数传递给可变长参数。使用如下:
注:传递数组是引用传递,传递基本数据类型为按值传递。
public class test {
public static void main(String[] arg){
printMax(5,8,9,1,35,88);
//或printMax(new double[]{5,8,9,1,35,88});
}
public static void printMax(double... numbers){
if(numbers.length==0){
System.out.println("Error");
}
double result = numbers[0];
for(int i = 1;i < numbers.length; i++)
if(numbers[i]>result)
result = numbers[i];
System.out.println(result);
}
}
为实现数组的排序和查找、数组的比较和对数组填充元素,java.util.Arrays类包括各种各样的静态方法。这些方法都有对所有的基本类型的重载方法。
double [] numbers = {6.0, 4.4, 1.9,......};
java.util.Arrays.sort(numbers); //对数组从小到大排序
char [] chars = {'a', 'A', '4',......};
java.util.Arrays.sort(chars, 1, 3) //对chars[1]到chars[3-1]排序
int[] list = {1, 5, 8, 9, 15,......} //数组必须提前按增序排列,才能使用binarySearch方法
java.util.Array.binarySearch(list, 1) //二分查找,数组必须提前按增序排列。若数组存在1,返回数组下 //标;若不存在,返回-(插入点下标+1)。
int[] list1 = {2,4,7,10};
int[] list2 = {2,4,7,10};
int[] list3 = {4,2,7,10};
java.util.Array.equals(list1,list2) //true
java.util.Array.equals(list1,list3) //false
int[] list1 = {2,4,7,10};
int[] list2 = {2,4,7,10};
java.util.Array.fill(list1,5) //用5填充整个list1,list1变为{5,5,5,5}
java.util.Array.fill(list2,1,3,8) //用8填充list[1]到list[3-1],list2变为{2,8,8,10}
int[][] x = new int[3][4]
x.length为3
x[0].length为4
public static int sum(int[][] m){
......
}
在类、方法和数据与前使用public修饰符,表示它们可以被任何其他的类访问。如果没有使用可见性修饰符,那么默认为类、方法和数据域是可以被同一个包中的任何一个类访问的。这称作包私有或包内访问。
private修饰符限定方法和数据域只能在它自己的类中访问。
Circle[] circle = new Circle[10]
构造一个字符串
char[] charArray = {'G','o','o','d',' ','D','a','y'};
String message = new String(charyArray);
String对象是不可变的,它的内容是不能改变的。
String s = "Java";
s="HTML";
第一条语句创建了一个内容为"Java"的String对象,并将其引用赋值给s。第二条语句参加了一个内容为"HTML"的新的String对象,并将其引用赋值给s。此时是变量s指向了新的对象,原来的"Java"对象还存在,只是无法访问了。
对具有相同字符串序列的字符串直接量使用同一个实例。这样的实例称为限定的。例如:
String s1 = "Welcome to Java";
String s2 = new String("Welcome to Java");
String s3 = "Welcome to Java";
System.out.println("s1 == s2 is " + (s1 == s2)); //false
System.out.println("s2 == s3 is " + (s1 == s3)); //true
concat(S1 : String) : String 返回连接这个字符串和字符串S1所构成的新字符串。
String s3 = s1.concat(s2);
String myString = message + " and " + "HTML"; //另一种组合方法
substring(beginIndex: int) : 返回这个字符串中以指定的beginIndex开始并延续到这个字符串末尾的字串。
substring(beginIndex : int , endIndex : int):返回这个字符串中以指定的beginIndex开始并延续到下标为endIndex-1的字符串的子串。
String message = "Welcome to Java".substring(0,11) + "HTML";
//变成"Welcome to HTML"。
toLowerCase() : 返回将所有字符都转换为小写之后的新字符串。
toUpperCase() : 返回将所有字符都转换为大写之后的新字符串。
trim() : 返回去掉两端的空白字符之后的新字符串。
replace(oldString : String , newString : String) : 返回用一个新字符串替换这个字符串中所有和它匹配的字符的新字符串。
replaceFirst(osdString : String , newString : String) : 与上面一个类似,只是替换第一个配备的字符串。
split(delimiter : String) : 返回用定界符分隔的字串所构成的一个字符串数组。
"Welcome".trim() //返回去掉空格的新字符串。
"Welcome".replace("e","AB") //返回一个新字符串"WABlcomAB"
"Java#HTML#Perl".split("#",0); //"Java HTML Perl"
"Welcome to Java".indexOf('W') //return 0
"Welcome to Java".indexOf('o',5) //从第5+1个字符之后第一次出现o的下标。return 9
"Welcome to Java".indexOf("come") //return 3
toCharArray() : 将字符串转换为数组
"Java".toCharArray() //返回将Java转换为数组的char[]
valueOf(char) : String
valueOf(char[]) : String
valueOf(double) : String
valueOf(float) : String
valueOf(int) : String
valueOf(boolean) : String
String.valueOf(5.44) //返回值是由字符'5','.','4','4'构成的字符串
String.format(format, item1, item2, … , itemk)
String.format("%5.2f", 45.556); //创建一个格式化的字符串"45.56"
isDigit(char) : boolean 如果指定字符是一个数字则返回true
isLettrer(char) : boolean 如果指定字符是一个字符则返回true
isLetterOrDigit(char) : boolean 如果指定字符是一个字符或数值则返回true
isLowerCase(char) : boolean 如果指定字符是一个小写字符则返回true
isUpperoCase(char) : boolean 如果指定字符是一个大写字母则返回true
toLoweCase(char) : char 返回指定字母的小写
toUpperCase(char) : char 返回指定字母的大写
StringBuilder / StringBuffer类是可以替代String类的另一种处理字符串的解决方案。
可以给一个StringBuilder / StringBuffer 中添加、插入或追加新的内容。
StringBuffer除了修改缓存区的方法是同步的之外,与StringBuilder 很相似。
如果是多任务并发访问,就使用StringBuffer;而如果是单任务访问,使用StringBuilder会更有效。
isLowerCase(char) : boolean 如果指定字符是一个小写字符则返回true
append(char[ ]) : StringBuilder 给这个字符串生成器追加一个char型数组。
append(char[ ], offset : int, len : int) : StringBuilder 将子数组追加给这个字符串生成器。
append(String) : StringBuilder 将一个字符串追加到这个字符串生成器。
delete(startIndex : int, endIndex : int) : 删除从startIndex到endIndex-1的字符。
deleteCharAt(index : int) : 删除指定下标处的字符。
insert(index : int, char[ ], offset: int,len : int) : 将数组中子数组插入到生成器的指定下标处。
replace(startIndex : int, endIndex : int , String) : 使特定的字符串替换生成器中从startIndex到endIndex-1的字符
reverse() : 颠倒生成器中的字符。
setCharAt(index: int, char) : void 在这个生成器中特定下标处设置一个新字符。
StringBuffer类提供了许多其他处理字符串生成器和获取它的属性的方法。
toString( ) : String 返回一个字符串对象
capacity( ) : int 返回这个字符串生成器的容量
charAt( ) : char 返回指定下标处的字
length( ) : int 返回这个生成器中的字符个数
setLength( int ) : void 在这个生成器中设置新的长度
trimToSize( ) : void 减少字符串生成器所使用的存储大小
File(String) : 为特定路径名创建一个File对象。
File(parent : String , child : String) : 为目录parent下的child创建一个File对象。child可以是一个文件名,也可以是一个子目录
exists( ) : boolean : 如果File对象表示的文件或目录存在则返回true
canRead( ) : boolean : 如果File对象表示的文件存在且可读则返回true
canWrite( ) : boolean : 如果File对象表示的文件存在且可写则返回true
isDirectory( ) : boolean : 如果File对象表示一个目录则返回true
isFile( ) : boolean : 如果File对象表示一个文件则返回true
isAbsolute( ) : boolean : 如果使用绝对路径名创建一个File对象则返回true
ishidden( ) : boolean : 如果File对象中表示的文件被隐藏则返回true。 被隐藏的确切定义是依赖系统的。
getAbsolute( ) :String:返回File对象表示的完整的绝对文件名或目录名
getName( ) : String : 返回File对象表示的完整的路径名和文件名的最后一个名字。
例: new File(“c:\book\test.dat”).getName()返回test.dat
getPath( ) : String : 返回File对象表示的完整的路径名和文件名
getParent( ) :String : 返回File对象表示的当前路径名和文件名的完整父目录
lastModified( ) : long:返回文件最后一次修改的时间
length( ) :long :返回文件的大小,如果文件不存在则返回0,如果是目录则返回目录大小
listFile( ) :File[ ] : 返回一个File对象目录下的文件
delete( ) :boolean:删除这个文件。如果删除成功则返回true
renameTo( dest : File) : boolean : 重命名这个文件。如果操作成功则该方法返回true
createNewFile() :boolean 创建文件,返回值表示是否创建成功. 当且仅当不存在具有此抽象路径名指定名称的文件时创建一个新的空文件;如果路径不存在,就不能创建文件
java.io.PrintWriter类可用来创建一个文件并向文本文件写入数据。首先必须为一个文本文件创建一个PrintWriter对象。
PrintWriter output = new PrinterWriter(filename);
如果文件不存在,调用构造方法会创建一个新的文件。如果文件已经存在,那么文件的当前内容将被废弃。
调用的构造方法可能会抛出异常。
PrintWriter(file : File) : 为特定的文件对象创建一个对象
PrintWriter(filename : String) : 为特定的文件名字符串创建一个对象
print(s : String) : void 向文件写入一个字符串
print(char) : void 向文件写入一个字符
print(char[ ]) : void 向文件写入一个字符数组
print(int) : void 向文件写入一个int型值
…
println(…) : void 多写入一个换行符,与上面一样。
必须使用close()方法关闭文件。如果没用调用该方法,数据就不能正确地保存在文件中。
java.util.Scanner类用来从控制台读取字符串和基本类型数组。Scanner可以将输入分为空格分隔的有用信息。
Scanner input = new Scanner(System.in);
为了从文件中读取,为文件创建一个Scanner类:
Scanner input = new Scanner(new File(filename));
close( ) :关闭这个扫描器
hasNext( ):boolean 如果这个扫描器还有可读的数据则返回true
next( ):String 从这个扫描器返回下一个标志作为字符串
nextLine( ):String 使用行分隔符从这个扫描器返回一个行结束的字符串
nextByte( ):byte 从这个扫描器返回的下一个标志作为一个byte值
nextShort( ):short 从这个扫描器返回的下一个标志作为一个short值
nextInt( ) :
nextLong( ) :
nextFloat( ) :
nextDouble( ) :
useDelimiter(pattern : String) : Scanner 设置这个扫描器的分隔模式并返回这个扫描器
方法nextByte(),nextShort( ),nextInt( ),nextLong( ) ,nextFloat( ),nextDouble( ),next( )等称为令牌读取方法,因为它们会读取用分隔符分隔的令牌。默认分隔符是空格。可以使用useDelimiter(String)设置新的分隔符模式。
如何工作?一个令牌读取方法首先会跳过任意分隔符,然后读取一个以分隔符结束的令牌。然后,对应于nextByte(),nextShort( ),nextInt( ),nextLong( ) ,nextFloat( )和nextDouble( ),这令牌就分别被自动地转换为一个byte、short、int、long、float、double型的值。对于next( )方法而言是无须做转换的。如果令牌和期望的类型不匹配,就会抛出一个运行异常。
public static void main(String[] arg){
Scanner input = new Scanner(System.in); //
int intValue = input.nextInt();
String line = input.nextLine();
System.out.println(intValue);
System.out.println(line);
}
Object o = new C(); //类C是Object类的子类,类C重新定义了toString
System.out.println(o.toString());
输出的是子类的toString方法
工作机制:有类C1,C2,…,Cn-1,Cn,其中C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类。若Cn是Object类,对象o是Cn的实例,若o调用一个方法p,那么Java虚拟机会依次在类C1,C2,…,Cn-1,Cn中查找方法p的实现,直到找到为止。一旦找到一个实现,就停止查找然后调用这个第一次找到的实现。
public class HidingDemo{
public static void main(String[] arg){
m(new C());
m(new B());
m(new A());
}
public static void m(Object x){
System.out.println(x.toString());
}
}
class A{
public String toString(){
return "A";
}
}
class B extends A{
public String toString(){
return "B";
}
}
class C extends B{
}
输出B \n B \n A \n
在今昔强制类型转换时,确保该对象是另一个对象的实例,这是可以利用运算符instanceof来实现的。
Object o = new Circle(); //类Circle是Object类的子类
if(o instanceof Circle){ //判断是否能转换
System.out.println( ((Circle)o).getDiameter() );//getDiameter方法是Circle特有的,只有强制转换后才能 调用子类的方法
}
注:对象成员访问运算符( . )优先于类型转换运算符。 例:((Circle) o) .getArea();
Java提供ArrayList类来存储不限定个数的对象。
ArrayList( ): 创建一个空的线性表
add( o: Object ): void 在这个线性表的末尾追加一个新元素o
add(index: int , o : Object ): void 在这个线性表的特定下标处增加一个新元素o
clear( ): void 从这个线性表中删除所有的元素
contains( o: Object): boolean 如果这个线性表包含元素o则返回true
get( index: int) : Object 返回这个线性表在特定下标处的元素
indexOf(o : Object): int 返回这个线性表中第一个匹配元素的下标
isEmpty( ):boolean 如果不包含元素则返回true
lastIndexOf( o: Object):int 返回这个线性表中最后一个匹配元素的下标
remove( o: Object):boolean 从这个线性表中删除元素o
remove( index : int): boolean 删除指定下标处的元素
size( ):int 返回这个线性表中元素的个数
set(index : int , o: Object): Object 设置在特定下标处的元素
经常需要允许子类访问定义在父类的数据域和方法,但不允许非子类访问这些数据域和方法。可以使用关键字protected完成该功能。
访问修饰符对比:
修饰符 | 当前类 | 同包 | 子类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
使用final修饰符表明一个类是终极的,是不能作为父类的。
public final class C{
}
也可以定义一个方法为终极的,一个终极方法不能被它的子类覆盖。
public class Test{
...
public final void m(){
...
}
}
如果方法可能会抛出多个异常,就可以在关键字throws后添加一个用逗号分隔的异常列表:
public void myMethod() throws Exception1,Exception2,...{
}
finally几种情况:
1、如果try块中没有出现异常,执行finally语句,然后执行try语句的下一条语句。
2、如果try块中有一条语句会引起异常,并被catch块捕获,然后跳过try块中的其他语句,执行catch块和finally子句。执行try语句之后的下一跳语句。
3、如果try块中有一条语句会引起异常,但没有被任何catch块捕获,就会跳过try块中的其他语句,执行finally子句,并且将异常传递给这个方法的调用者/
即使在到达finally块之前有一个return语句,finally块还是会执行。
抽象方法:在方法头使用abstract修饰符表示。有抽象方法的类就是抽象类
抽象类:在类头使用abstract修饰符表示。
抽象类和常规类很像,但是不能使用new操作符创建它的实例。抽象方法只有定义而没有实现。它的实现由子类提供。一个包含抽象方法的类必须声明为抽象类。
具体看代码:(因为动态地决定调用哪一个方法)
public class Test{
//类G是抽象类;类C表示圆,是G的子类;类R表示矩形,是G的子类。两个子类分别实现抽象方法getArea()
public static void main(String[] args){
G g1 = new C(5);
G g2 = new R(5,3);
System.out.println("have the same area? " + equalArea(g1,g2));
}
public static boolean equalArea(G a,G b){
return a.getArea() == b.get Area(); //会在运行时根据对象的类型动态地决定调用哪一个方法
}
}
1、抽象类不能包含在非抽象类中。如果抽象类的子类不能实现所有的抽象方法,那么子类也必须定义为抽象的。抽象方法是非静态的。
2、抽象类是不能使用new操作符来初始化的。但是,可以定义一个不包含抽象方法的抽象类。
3、即使子类的父类是具体的,这个子类也可以是抽象的。
4、子类可以覆盖父类的方法并将它定义为abstract。在这种情况下,子类必须定义为abstract。
5、不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。例如:
G[ ] g = new G[10]
接口在许多方面都与抽象类很相似,但是它的目的是指明多个对象的共同行为。
类和接口之间的关系称为接口继承。
可以使用接口作为引用变量的数据类型或类型转换的结果。
例如:B b = new A(); //B是接口,A继承B的接口。
一个接口的变量可以引用任何实现该接口的类的实例
public interface Cloneable{ //空的
}
这个接口是空的。一个带空体的接口称为标记接口。它用来表示一个类拥有某些特定的属性。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用在Object类中定义的clone( )方法克隆。如果不继承自Cloneable接口,当调用clone()时会抛出CloneNotSupportedException异常。
如果一个数据域是基本类型,clone复制的就是它的值。如果一个数据域是对象,复制的就是该域的引用。
clone是浅复制而不是深复制。
class A implement Cloneable{
private int id;
private B b;
public A(int id,B b){
this.id=id;
this.b=b;
}
}
main(){
A a1 = new A(1, B );
A a2 = a1.clone(); //浅复制,如果要深复制需要自定制的克隆操作来覆盖clone方法
}
变量 | 构造方法 | 方法 | |
---|---|---|---|
抽象类 | 无限制 | 子类通过构造方法链调用构造方法,抽象类不能用new操作符实例化 | 无限制 |
接口 | 所有的变量必须是public static final | 没有构造方法。接口不能用new操作符实例化 | 所有方法必须是公共的抽象实例方法 |
Java允许使用接口做多重扩展
public class NewClass extends BaseClass implements Interface1,... ,InterfaceN{
}
接口可以利用关键字extends继承其他接口。
public interface NewInterface extends Interface1, ... ,InterfaceN{
}
如果要进行非常大的数的计算或者高精度浮点值得计算,可以使用java.math包中的BigInteger类和BigDecimal类。
它们都是不可变的。它们都扩展Number类且实现Comparable接口。
BigInteger的实例可以表示任意大小的整数。
算术运算方法:
add、subtract、multiple、divide和remainder
BigInteger a = new BigInteger("9999999999999999999999999");
BigInteger b = new BigInteger("2");
BigInteger c = a.multiple(b);
System.out.println(c);
对BigDecimal对象的精度没有限制。如果做除法除不尽,那么divide方法会抛出ArithmeticException异常。但是可以使用重载的divide(BigDecimal d, int scale, int roundingMode)方法来指定尺度和舍入方式来避免这个异常,这里的scale是指小数点后最小的整数位数。