java.util.Scanner.out.ptintln
System.out.println(x = 1)
是正确的int x = 1; System.out.println(x);
final double PI = 3.14159
Scanner input = new Scanner(system.in)
Math.pow(a,b)
可以计算a^b并返回结果,Math类隐藏在java.lang包中,此包为隐式导入的,因此,不需要在开始声明。System.out.println(Math.pow(2,3))
5.0/2=2.5 5/2.0=2.5 5/2=2
l or L
来示意这个数值是long类型 如2147483648L
同理1010.2d
代表double 1002F
代表float 这里不区分大小写0B1111=15
07777=4095
0XFFFF=65535
124_123=124123
System.currentTimeMillis()
可以返回从1970年1月1号到现在的毫秒数int a = ++i;
先加了 返回新值int a = i++;
加了但返回旧值double x = 1.0;
double y = 5.0;
double z = x-- + (++y);
x=0.0 y=6.0 但z=7.0
5.从左到右对操作数求值 此规则高于一切
int i = 1;
int k = ++i + i*3
i = 2, k =8
int i = 1;
int k = i++ + i*3
i = 2, k = 7
6.应该避免在同一个表达式中多次使用该规则防止混乱
(double)8为8.0
int sum = 0;
sum += 4.5;
//sum += 4.5 等价于 sum = (int)(sum += 4.5)
//该式子是正确的
int i = 1;
byte b = 1;//错误 必须使用显性的类型转换
int i = 1;
byte b = (byte)i;//正确
(int)(tax * 100) / 100 //默认——将tax向下四舍五入保留小数点后两位
(int)(x + 0.5) //将任意的tax向上四舍五入
==>
(int)(x * 100 + 0.5)/100
int a = 1;
double a = 1.0;
//会报错重复变量
package demo;
import java.util.Scanner;
public class Plus {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a number between 0 and 1000:");
int number = input.nextInt(); //输入一个三位数
int units = number % 10; //932 % 10 = 2 并赋给个位
number = number / 10; //932 / 10 = 93 修改number的值
int tens = number % 10; //93 % 10 = 3
number = number / 10; //93 / 10 = 9
int huns = number;
int plus = huns + tens + units;
System.out.println(plus); //9+3+2=14
}
}
if(boolean){}
if() //if后面没有分号 有分号则等于后面有一个空的块 如if{}; 这是一个逻辑错误 很难被发现
{}
else if()
{}
else if()
{}
else
{}
final double EPSILON = 1E-14;
double x = 1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1;
if (Math.abs(x - 0.5) < EPSILON) //与0.5无限接近
System.out.println(x + "is approximately 0.5");
Math.random() //可以获得一个0.0到1.0之间的随机double值,不包括1.0
(int)(Math.random() * 10) //因此可以获得一个0~9的整数
! //非
&& //与
|| //或
^ //异或
p1 ^ p2 == p1 != p2
switch(year % 12){ //输入一个值 不可以是判断
case 1:
break;
case 2:
break;
default: ; //默认语句
}
max = (num1 > num2) ? num1 : num2;
若是括号里的为true,则执行结果为第一个代码块,若为false,则执行结果为第二个代码块。
右边的执行完毕后,再赋值给左边的max,起到取大的效果。
所有二元操作符都是左结合的
所有的赋值运算符是右结合的 因此
a = b += c = 5 等价于 a = (b += (c = 5))
先与后或再赋值
sin(radians),asin(a),toRadians(degree),toDegrees(radians);
exp(x),log(x),log10(x),pow(a,b),sqrt(x)//x >= 0;
ceil(x),floor(x),rint(x),round(x)
a + Math.random() * b; //返回a ~ a+b之间的一个随机数,不包括a+b
15 + Math.random() * 30; //返回15~44的一个随机数
char用于表示单个字符,用单引号扩住。
而字符串字面值必须扩在双引号中。
因此,"A"是一个字符串,'A’是一个字符。
字符 | 十进制编码值 | Unicode值 |
---|---|---|
'0' ~ '9' |
48~57 | \u0030~ \u0039 |
'A' ~ 'Z' |
65~90 | \u0041 ~ \u005A |
'a' ~ 'z' |
97~122 | \u0061 ~ \u007A |
char letter = 'A';
char letter = '\u0041';
//这两行语句等价
char ch = 'a';
System.out. println(++ch);
//将输出字符b
char型数据可以转换成任意一种数值类型,反之亦然,将整数转换成char类型只用到该数据的低16位。
char ch = (char)0XAB0041;
System.out.println(ch);
//char为A
char ch = (char)65; //0041(16)== 65(10)
System.out.println(ch);
//char为A
//第一个char是16进制,将其转换的原理为先截取后四位,再转换为十进制值对应十进制编码值输出。
//0041(16)== 65(10),因此上面两式子是等价的。
char ch = (char)0041;
System.out.println(ch);
//char为!
//如果直接截取后四位将其作为十进制数处理,结果将不同,是错误的。
int i = (int)'A';
//i is 65.
String s = input.next() //以空格区分 字符串中不能有空格
String s = input.nextLine(); //可以有空格 输入单个字符也用它
int int1 = Integer.parseInt(intString);
double double1 = Double.praseDouble(doubleString);
String s = Integer.valueOf(23).toString();
String s = Double.valueOf(23).toString();
s.length();
array.length
Math.pow(2,2.5)
"jfisogh".lenth();
是正确的month == "Feb";
//是错误的 它永远为false
month.equal("Feb");
//是正确的
//类型不匹配:不能从 char 转换为 String
%10.2f
输出的浮点数的宽度至少为10,包括小数点和小数点后的数字,即前面至少7位整数,小于则加空格,大于则自动增加宽度,后面保留两位小数。%10.2e输出123.0为001.23e+02
while(){
}
---
do{
}while(); //只有dowhile有分号
---
for( ; ; ){
}
int i = 1;
while (i < 10)
if(i % 2 ==0 )
System.out.println(i);
//无限循环错误 没有出现自增模块
int i = 1;
while (i < 10)
if(i % 2 == 0)
System.out.println(i++);
//无限循环错误 自增模块在if里没机会得到执行
int i = 1;
while (i < 10)
if((i++) % 2 == 0) //先以i=1判断 然后在下一句语句中得到自增
System.out.println(i); //在i = 2,4,6,8 得到满足
//输出i = 3,5,7,9
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis();
long testTime = endTime - startTime;
System.out.println(testTime/1000);
double item = 1; double sum = 0;
while(item != 0){
sum += item;
item -= 0.1;
}//item永远不可能减到完全等于0,它会跳过0向负数进发,这将是一个无限循环。
java ClassName < input.txt
//输入重定向,前面的是类名,将后面文件里面的数据导入类。
java ClassName > output.txt
//输出重定向,将类中产出的数据导入文件。
java CLassName < input.txt > output.txt
//输入输出重定向 先输入后输出 看起来就像把input文件括在里面
do-while至少执行一次,某些情况下这两种会有一种更方便。
do-while改成while的话,**某些语句需要在循环前和循环内重复出现以达到至少执行一次的效果。**如:
基本上都可以转换 但是for循环定义的变量是在内部,不会影响到后面的代码。
while循环定义的变量是会影响到之后的代码的。
for(int i = 0; i < 10; i++)
for(int j = 0; j < i; j++)
System.out.println(i * j);
//该程序执行了多少次?
//45次 = 1*1 + 2*2 + …9*9
在循环条件中使用浮点数将导致数值错误。
浮点数不够精确 可能会导致无限循环
double item = 1; double sum = 0;
while(item != 0){
sum += item;
item -= 0.1;
}//item永远不可能减到完全等于0,它会跳过0向负数进发,这将是一个无限循环。
for(double i = 0.01; i ,<= 1.0; i = i + 0.01)
sum += i;
// i可能最后会比1稍微大一点,而这将导致最后一次求和失败!数据偏差将会很大。
package demo;
import java.util.Scanner;
public class Dec2Hex {
public static void main(String[] args) {
char a = ' ';
do {
Scanner input = new Scanner(System.in);
System.out.print("Please input a Dec:");
int dec = input.nextInt(); //将十进制数存入dec变量
String hex = " "; //定义一个空字符串
do{
int hexValue = dec % 16; //个位等于十进制数对16取余
char hexDigit = (0 <= hexValue && hexValue <= 9) ?
(char)(hexValue + '0') : (char)(hexValue - 10 + 'A');
//定义一个字符,如果个位在0~9之间,则将其与'0'相加,
//此时的答案是一个ASCII码,如45。
//再通过char将其转化为字符,如'2'。
//如果在10到16之间,则通过 - 10 + 'A'来计算。
//如11 => 66 => B
hex = hexDigit + hex;//将其插入空字符串的前面
//注意:此处后面两个变量位置不能互换。
dec = dec / 16;//新的十进制数由十进制数除以16得出
}while(dec != 0);//直到dec/16为0为止,也就是dec<16为止
//此时的dec就是16进制的最大位数上的数
System.out.println("The hex number is:" + hex);
System.out.print("Put Y to continue and N to exit:");
a = input.next().charAt(0);
//取一个字符串,并返回它的第一个字符给a。
}while(a == 'Y');//如果a为'Y',则重新开始第一个循环。
}
}
break跳出整个循环
continue跳出一次循环 直接下一次
package demo;
import java.util.Scanner;
public class Hex2Dec {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a hex number: ");
String hex = input.nextLine();
System.out.println("The decimal value for hex number "
+ hex + " is " + hexToDecimal(hex.toUpperCase()));
}
public static int hexToDecimal(String hex){
int decimalValue = 0;
for (int i = 0; i < hex.length(); i++){
char hexChar = hex.charAt(i);
decimalValue = decimalValue * 16 + hexCharToDecimal(hexChar);
}
return decimalValue;
}
public static int hexCharToDecimal(char ch){
if (ch >= 'A' && ch <= 'F')
return 10 + ch - 'A';
else
return ch - '0';
}
}
输出一个数的反序数(ReverseNumber)
package demo;
import java.util.Scanner;
public class ReverseNumber {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please inter a int number: ");
int number = input.nextInt();
reverse(number);
}
public static void reverse(int number)
{
StringBuilder str = new StringBuilder(number + "");
//利用StringBuilder方法来新建一个string字符串以方便修改
int length = str.length();
for(int j = 0,k = 1; j < length - 1; j++,k++) {
//一共循环长度-1次,并定义k变量来每次排序后将排序位数减一
for (int i = 0; i < length - k ; i++)
{ char a = str.charAt(i);
char b = str.charAt(i + 1);
str.setCharAt(i , b);//利用setCharAt方法
str.setCharAt(i + 1 , a);//将提取出来的两个位置上的字符互换
}
}
System.out.println("The inversion number is: "+ str);
}
}
double[] myList;
或者double myList[];
来声明数组变量。myList = new double[10];
double myList[] = new double[10];
myList[0] = 5.6;
arrayRefVar.length
获取大小myList.length
为10。 double[] myList = {1.9, 2.9, 3.4, 3.5};
//这条语句声明、创建并且初始化包含4个元素的数组myList。
//大括号!!!
//该语句相当于
double[] myList = new double[4];
myList[0] = 1.9;
myList[1] = 2.9;
myList[2] = 3.4;
myList[3] = 3.5;
for(int i = 0; i < myList.length; i++)
System.out.print(myList[i] + " ");
//数值类型的数组需要for循环。
char[] city = {'a','a'};
System.out.print(city);
//char类型的数组可以直接打印。
for (double e : myList)
System.out.print(e);
//对myList中每个元素e进行以下操作,即遍历整个数组。
//注意:变量e的数据类型必须与数组类型相同。
arraycopy(原数组,原数组起始位置,目标数组,目标数组起始位置,元素个数)
System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);
System.arraycopy(source, 0, t, 0, source.length);
//用此方法前要先声明目标数组并分配内存空间。
swap(a[0], a[1])
public static void swap(int a1, int a2){}
//这样改变的只是实参,而不会涉及数组。 ×
swap(a)
public static void swap(int[] array){}
//这样传递的是整个数组。 √
public static viod printMax(double…numbers) {
if (numbers.length == 0)
System.out.println("No argument passed");
return;
}
package demo;
public class BinarySearch {
//二分查找法(不含main函数)
public static int binarySearch(int[] list, int key) {
int low = 0;
int high = list.length - 1;
while (high >= low) { //此处不能用 > ,不然对只有一个元素的数组无法处理。
int mid = (low + high) / 2;
if (key < list[mid])
high = mid - 1;
else if (key == list[mid])
return mid;
else {
low = mid + 1;
}
}
return -low-1;
}
}
package demo;
import java.util.Scanner;
public class SelectSort {
//选择排序算法:从所有数中选择最小的与第一个交换。
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] list = { 5, 2, 3, 7, 9, 8, 1 };
for (int j = 0; j < list.length - 1; j++) {//用j < list.length 也可运行,但是要多运算一步。
int min = list[j];//将第一个值赋给min,后面的值与其比较。
int tag = j;
for (int i = j + 1; i < list.length; i++) {//用i = j也可运行,但是要多运算一步。
if (list[i] < min) {
min = list[i];//记录最小值。
tag = i;//标记最小下标。
}
}
list[tag] = list[j];
list[j] = min;//将当前最前面的值于min所处位置的值交换。
}
for (int e : list)
System.out.println(e);//for each循环输出。
}
}
Arrays.sort(list, indexStart, indexEnd);//从小到大对start和end里面进行排序,不包括end。
Arrays.parallelSort();//同上,但是多处理器这个会快些。
Arrays.binarySearch();//二分查找法,必须提前按升序排好。
Arrays.equals(list1, list2);//严格比较相等,一对一。
Arrays.fill(list1, 5);//使用5填充整个数组。
Arrays.fill(list1, 1, 5, 8);//使用8填充1至5地址,不包括5。
Arrays.toString(list);//将数组返回成一个字符串。
main就像一个普通的函数,它可以接收字符串args。
不仅可以直接在其他类调用它,还可以从命令行向他传递参数。
int[][] matrix;
matrix = new int[5][11];
//两句可以合并成一句:
int[][] matrix = new int[5][12];
matrix[2][14] = 7; //是正确的
matrix[2,7] = 7; //是错误的
array.length//行数
array[0].length//第一行的长度
int[][] array ={
{1,2,3},
{1,2,3},
}
int[][] array2 ={
{1,2,3},
{1,2},
}//不规则数组是被允许的
如果不想一开始就给不规则数组赋值 可以使用空括号
int[][] array = new int[5][];
//第一个括号必须有值。
package demo;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int[][] m = getArray();
System.out.println("\nSum of all elements is " + sum(m));
}
// 返回一个二维数组
public static int[][] getArray() {
Scanner input = new Scanner(System.in);
int[][] m = new int[3][15];
System.out.println("Enter " + m.length + " rows and " + m[0].length + " columns: ");
for (int i = 0; i < m.length; i++)
for (int j = 0; j < m[i].length; j++)
m[i][j] = input.nextInt();
return m;
}
// 对一个二维数组求和
public static int sum(int[][] m) {
int total = 0;
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++)
total += m[i][j];
}
return total;
}
}
//for(int e :list)
//System.out.print(e);
package demo2;
import java.util.Scanner;
public class MultiplyMatrix {
//矩阵乘法
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入第一个矩阵的行数和列数,如(2 3):");
int arow = input.nextInt();
int acol = input.nextInt();
int[][] a = new int[arow][acol];
System.out.print("请输入第二个矩阵的行数和列数,如(2 3):");
int brow = input.nextInt();
int bcol = input.nextInt();
int[][] b = new int[brow][bcol];
if (arow != bcol) {
System.out.print("Input invalid.");
System.exit(0);
}
System.out.println("请输入第一个矩阵的数值:");
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
a[i][j] = input.nextInt();
}
}
System.out.println("请输入第二个矩阵的数值:");
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[0].length; j++) {
b[i][j] = input.nextInt();
}
}
int[][] c = multiplyMatrix(a, b);
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c[0].length; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
public static int[][] multiplyMatrix(int[][] a, int[][] b) {
if (a.length != b[0].length) {
System.out.print("The input is invalid.");
return null;
}
int[][] c = new int[a.length][b[0].length];
int length = a.length;
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
for (int j2 = 0; j2 < a[0].length; j2++) {
c[i][j] += a[i][j2] * b[j2][j];
}
}
}
return c;
}
}
UML类图详解:https://www.cnblogs.com/pangjianxin/p/7877868.html
static int getNumberOfObjects() {
return numberOfObjects;
}
可以直接通过类名调用而不用声明对象
Circle.getnumberOfObjects;
Circle[] cir = new Circle[5];
for (i = 0; i < Circle.length; i++) //创建一个新数组。
cir[i] = new Circle(); //为每一个成员初始化。
public class Student{
private java.util.date dateCreated;
public java.util.Date getDateCreated{
return dateCreated;
}
}
public class Test {
public static void main(String[] args){
Student student = new Student(m223333, "John");
java.util.Date dateCreated2 = student.getDateCreated();
// 传出了dateCreated对象的引用
// dateCreated2和dateCreated其实指向的是同一个对象
dateCreated2.setTime(200000);
// 达到修改对象的目的
因此要创建一个不可变对象,要满足三点:
https://blog.csdn.net/Return_head/article/details/80744056
1.假如在一个构造方法中使用了this语句,那么它必须作为构造方法的第一条语句(不考虑注释语句)。
2.只能在一个构造方法中使用this语句来调用类的其他构造方法,而不能在实例方法中用this语句来调用类的其他构造方法。
3.只能用this语句来调用其他构造方法,而不能通过方法名来直接调用构造方法。
java.math.BigInteger
。初始化:BigInteger sum=new BigInteger("0");
加法:sum=sum.add(n1); //这里sum和n都为BigInteger类型
减法:sum=sum.subtract(n1);
乘法:sum=sum.multiply(n1);
除法:sum=sum.divide(n1);
幂运算:sum=sum.pow(10);
取相反数:sum=sum.negate();
java.math.BigDecimal
.初始化:BigDecimal num1=new BigDecimal("1234.56453324");
加法:sum=sum.add(n1); //这里sum和n都为BigDecimal类型
减法:sum=sum.subtract(n1);
乘法:sum=sum.multiply(n1);
除法:sum=sum.divide(n1);
将BigDecimal类型转换为double类型:num1.doubleValue();
比较大小:num1.compareTo(num2);
//小于时,返回-1; 等于时,返回0; 大于时,返回1。
四舍五入处理:
num1.divide(num2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
//scale表示保留几位小数
String类源码:
https://blog.csdn.net/ylyg050518/article/details/52352993
String message = new String("hello");
// 一般用法
String message = "hello";
// Java将字符串直接看做String对象,这样也合法。
String s = "Java";
s = "HTML": ;
// "Java"对象被抛弃,s引用为新的string对象"HTML"。
String s1 = "Welcome to ]ava";
String s2 = new String("Welcome to ]ava");
String s3 = "Welcome to ]ava";
//s1 == s3, s1 != s2;
str.replace('a','b');
str.replaceAll("ab","abc");
String[] tokens = "Java#HTML#Perl".split("#");
for (int i = 0; i < tokens.length; i++)
System.out.print(tokens[i] + " ");
// split将字符串分割成了三个小字符串并存入数组。
//显示Java HTML Perl
"Java".matches("Java");
"Java is fun".matches("Java.*");
"Java is cool".matches("Java.*");
//字符串.*与零个或多个字符相匹配。
// . 任意字符 *任意长度
String s = "a$b%c^".replaceAll("[$%^]","NNN");
System.out.println(s);
//aNNNbNNNcNNN
String[] tokens - "Java.C?C#,C++".split("[.,:;?]");
for (int i = 0; i < tokens.length; i++) System.out.println(tokens[i]+" ");
//Java C C# C++
char[] a = "Java".toCharArray();
char[] dst = {'J','A','V','A','1','3','0','1'};
"CS3720".getChars(2,6,dst,4);
//dst{'J','A','V','A','3','7','2','0'};
String str = new String(new char[]{'a','a'});
// 可以直接使用构造方法。
String str = String.valueOf(new char[]{'a','a'});
// 也可以使用valueOf方法。
Double.parseDouble(str);
Integer.parseInt(str);
String a = String.valueOf(5.44);
//a:{'5','.','4','4'}
String s = String.format("%7.2f%6d%-4s", 45.556, -4s, "AB");
System.out.println(s)
//□□45.56□□□□14AB□□
注意
System.out.printf();
等价为
System.out.print(String.format());
StringBuilder StringBuilder = new StringBuilder();
stringBuilder.append("Welcome");
stringBui1der.append(' ');
stringBuilder.append("to");
stringBui1der.append(' ');
stringBui1der.append("Java");
//"Welcome to Java"
//"Welcome to Java"
StringBuilder.insert(11, "HTML and ");
//"Welcome to Html and Java"
stringBui1der.delete(8,11) // Welcome Java。
stringBuilder.deleteCharAt(8) // Welcome o Java。
stringBuilder.reverse() // avaJ ot emocleW。
stringBuilder.replace(11,15,"HTML") // Welcome to HTML。
stringBuilder.setCharAt(0,'w') // welcome to Java
package demo2;
import java.util.Scanner;
public class PalindromelgnoreNonAlphanumeric {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("input a string: ");
String s = input.nextLine();
System.out.print(s + " " + isPalindrome(s));
}
public static boolean isPalindrome(String s) {
StringBuilder s1 = new StringBuilder();
//将字符串转换为stringbuilder对象
for(int i = 0; i
package demo2;
public class MyString1 {
private final char value[];
public static void main(String[] args) {
// char[] a = "Hello World".toCharArray();
// MyString1 s = new MyString1(a);
// char[] b = "Hello World".toCharArray();
// MyString1 s2 = new MyString1(b);
System.out.print(MyString1.valueOf(123455).value);
}
public MyString1(char[] chars) {
value = chars;
//源码中用copy实现
}
public MyString1() {
this.value = new char[0];
}
public char charAt(int index) {
return value[index];
}
public int length() {
return value.length;
}
public MyString1 substring(int begin, int end) {
char[] newValue = new char[end - begin];
for (int i = begin, j = 0; i < end; i++, j++) {
newValue[j] = value[i];
}
MyString1 s1 = new MyString1(newValue);
return s1;
}
public MyString1 toLowerCase() {
MyString1 s1 = new MyString1(value);
for (int i = 0; i < s1.value.length; i++) {
if (s1.value[i] >= 'A' && s1.value[i] <= 'Z') {
s1.value[i] = (char) (s1.value[i] - 'A' + 'a');
}
}
return s1;
}
public boolean equals(MyString1 s) {
boolean isequal = true;
if (s.length() != value.length) {
return false;
}
for (int i = 0; i < s.length(); i++) {
if (s.value[i] != value[i])
isequal = false;
}
return isequal;
}
public static MyString1 valueOf(int i) {
int digit = 1;
int k = i;
while (k / 10 > 0) {
digit++;
k = k / 10;
}
char[] ch = new char[digit];
for (int j = digit - 1; j >= 0; j--, i = i / 10) {
if (j == 0) {
ch[j] = (char)(i + 48);
} else {
ch[j] = (char)((i % 10) + 48);
}
}
return new MyString1(ch);
}
}
public class Circle extends CeometricObject
// Subclass 继承于 Superclass
super
用来指代上一个父类,可以用来调用父类的普通方法和构造方法。super
,而不能使用构造方法名。普通函数
super.toString();
Superclass.toString();
// 等价
构造函数
super();
// 正确
Superclass();
// 错误!在子类中不能直接用函数名调用父类的构造函数,只能使用super。
super()
和super(arguments)
必须出现在子类构造方法的第一行。super
,那就会默认在第一行加入隐形的super
函数(无参),来调用父类的无参构造方法。public ClassName(double a){
//some statements
}
等价于
public ClassName(double a){
super();
//some statements
}
因此,如果父类没有无参构造方法,会出现一个错误。
问题:子类继承了父类的普通方法,那为什么还要用super调用父类的普通方法?
POINT:
要重写一个方法,需要在子类中使用和父类一样的签名以及一样的返回值类型来对该方法进行定义。
重写标注:@Override
Java中的所有类都继承自java.lang.Object类。
因此Object类是所有类的父类,他其中有toString()方法。
一般情况下,toString( )返回 [类名@地址]
这没有什么用,因此一般需要重写toString( )方法。
Object类中的euqals()方法用来测试两个对象是否相等
object1.equals(object2);
默认的equals只能判断两个是否指向同一对象。
注意,在object类中,equals的参数是object类,因此重写的时候要遵循这个规则。
public boolean equals(Circle o){
} //是错误的
public boolean equals(Object o){
} //是正确的
例子:
public class Text {
public static void main(String[] args) {
Object a = new Circle();
Object b = new Circle();
System.out.print(a.equals(b));
}
1.
public class Circle {
double radius;
public boolean equals(Object circle) {
return this.radius == ((Circle) circle).radius;
}
}// 输出为true。两者的半径相同。
2.
public class Circle {
double radius;
public boolean equals(Circle circle) {
return this.radius == circle.radius;
}
}// 输出为false。它根本就没有调用Circle里的这个euqals方法,因为传入的值是object类型,它直接调用了Object类中的equals去了!因为比较的是引用,两者没有指向同一个变量,所以为false。
面向对象程序设计的三大支柱是封装、继承和多态。
方法可以在沿着继承链的多个类中实现。JVM决定运行时调用哪个方法。
Object o = new GeometricObject();
//声明类型 实际类型
对象转换和强制类型转换很像。可以将子类隐式转换为父类,但父类下来必须用强制转换。就像byte可以直接转换为int,但是int赋值给byte而不用(int)byte就会出错。
Object o = new Student;
// 可以将一个Student对象的引用赋给object变量
Student b = o;
// 错误!原因是Student对象总是Object的实例,但是,Object对象不一定是 Student的实例。
// 即使可以看到o实际上是一个Student的对象,但是编译器还没有聪明到知道这一点。
Student b = (Student)o;
转换记住左大右小。
Object a = new Circle();
if(a instanceof Circle){
// *使用instanceof关键字*来确定这个实例是不是这个类的实例。
System.out.print(((Circle)a).getYou());
}
// 然后再将Object变量的*引用强制转换*为对Circle对象的引用,才能调用Circle中的getYou方法。
即使需要进行如此复杂的对象类型转换,一开始也要定义为父类(Object),这样,它就能接受任意子类型的值。
((class)a).getYou();
可以创建一个数组存储对象,但是这个数组一旦创建,它的大小就固定了。
因此,Java提供ArrayList类来存储不限定个数的对象。
即可变对象列表(不叫数组)。
import java.util.ArrayList
ArrayList a = new ArrayList();
JDK1.7后也可以简写为
ArrayList a = new ArrayList<>();
ArrayList和数组可以相互转换。
将数组转换为列表
String[] a = {"a","b","c"};
ArrayList list = new ArrayList<>(Arrays.asList(a));
// 使用Arrays类中的静态方法asList()。
将列表转换为数组
String[] b = new String[list.size()];
list.toArray(b);
// ArrayList类中的普通方法toArray()将list中的元素复制到数组内。
java.util.Collections类中有一些有用的方法。如:排序,最大值,随机打乱。
import java.util.Collections
Intege [] array = {3, 5, 95, 4, 15, 34, 3, 6, 5};
ArrayList list = new ArrayList<>(Arrays.asList(array));
Collections.sort(list);
// 排序
Collections.max(list);
Collections.min(list);
Collections.shuffle(1ist);
// 随机打乱
一个类中的受保护成员可以从子类中访问。
在UML类图中,protected的方法前面加#
可以看出,protected只比默认开放一点点,只是增加了在继承类中可以访问,而在不同包里仍不可以访问。而同一个包里不管继不继承,只要不是private就可以访问
异常是从方法抛出的。方法的调用者可以捕获以及处理该异常。
异常需要消耗系统资源,因此,可以预料的错误尽量使用if。
并且,不要将异常处理当做简单的逻辑测试。
try
字块内之后的语句就不会再运行。public static int quotient(int num1,int num2){
if (num2 == 0){
public static void main(String[] args){
try{
int result = quotient(1, throw new ArithmeticException("Divisor can not be Zero. ")
}
return num1 / num2;
}
0);
System.out.print(result);
} //如果遇到异常,则抛出一个异常对象,并被catch捕获。
catch(ArithmeticException ex){
//程序跳转至catch功能块,并在处理完catch块后接着往下运行。
System.out.print("Invaild input. ")
}
}
throws
public void method() throws IOException
//多个异常
public void method()
throws IOException,Exception2,Exception3...ExceptionN
IllegalArgumentException ex = new IllegalArgumentException("Wrong Argument");
throw ex;
//可以使用简写
throw new IllegalArgumentException("Wrong Argument");
throws
,抛出异常的关键字是throw
。getMessage()
获取。try{
statements;
}
catch (Exception1 exVarl){
handler for exceptionl;
}
catch (Exception2 exVar2){
handler for exception2;
}
..
catch (ExceptionN exVarN){
throw exVarN;// Java允许重新抛出异常。
}
//JDK7的新的多捕获特征可以用来简写
catch(Exception1 | Exception2 | ... | ExceptionN){
//same handling these exceptions
}
try{
statements;
}
catch(TheException ex){
handling ex;
}
finally{
finalStatements;
}
和其他异常一起抛出一个异常,形成了链式异常。
catch(Exception ex){
throw new Exception("new error", ex);
}
可以通过派生java.lang.Exception
类来定义一个自定义异常类。
public class InvalidRadiusException extends Exception {
private double radius;
● public InvalidRadiusException(double radius) {
● super("Invalid radius " + radius);
//调用父异常类Exception的构造方法。
this.radius = radius;
}
public double getRadius() {
return radius;
}
}
java.io.File类包含了获得一个文件/目录的属性,以及对文件/目录进行改名和删除的方法。
c:\book\Welcome.java
绝对文件名是依赖机器的,
而相对文件名是相对于当前工作目录的。
Welcome.java
如果当前工作目录是c:\book
绝对文件名: c:\book\Welcome.java
Windows:" \ "
// Java中,反斜杠要写成"\\"
new File("c:\\book\\test.dat")
Unix: " / "
// Java支持直接使用"/"
new File("c:/book/test.dat")
使用Scanner类从文件中读取文本数据,使用PrintWriter类向文本文件中写入数据。
Java.io.PrintWriter
类可以用来创建一个文件并写入数据。PrintWriter output = new PrintWriter(filename);
close()
来关闭文件。注意:PrintWriter可以直接使用File类的对象作为构造方法的参数。
也就是说它可以以指定文件名创建对象,也可以直接利用现成的File类对象。
调用PrintWriter类构造方法将直接新建一个文件。
public class WriteData {
public static void main(String[] args) throws IOException{
//使用File类来检测scores.txt是否已经存在
java.io.File file = new java.io.File("scores.txt");
if(file.exists()){
System.out.println("File already exists");
System.exit(1);
}
//直接新建一个文件,利用File的对象file
java.io.PrintWriter output = new java.io.PrintWriter(file);
//调用实例方法来写入文件
output.print("John T Smith ");
output.println(90);
output.print("Eric K Jones ");
output.println(85);
//不要忘记关闭文件
output.close();
}
}
你知道的,程序员总是会忘记关闭文件。所以我们可以使用try-with-resources语法来自动关闭资源。
try(声明和创建资源)
{
处理文件;
}
注意:try后面跟着的是小括号()
public class WriteData {
public static void main(String[] args) throws IOException{
//使用File类来检测scores.txt是否已经存在
java.io.File file = new java.io.File("scores.txt");
if(file.exists()){
System.out.println("File already exists");
System.exit(1);
}
//在try的括号中声明并新建
● try(
java.io.PrintWriter output = new java.io.PrintWriter(file);
){
//调用实例方法来写入文件
output.print("John T Smith ");
output.println(90);
output.print("Eric K Jones ");
output.println(85);
}// 不需要用到close方法!
}
}
Scanner input = new Scanner(new File(filename));
throws Exception
注意:new Scanner(String)为给定的字符串创建一个Scanner对象。
等价于:从给定的字符串读取数据。
当要从文件读取数据时,要先用new File(filename)创建一个File对象,
然后用new Scanner(filename)来从文件读取数据。
scores.txt
{
John T Smith 90
Eric S Cgjlj 99
}
public class ReadData {
public static void main(String[] args) throws IOException{
● java.io.File file = new java.io.File("scores.txt");
try(
● Scanner input = new Scanner(file);
){
while(input.hasNext()){
//每次迭代(到没有标记为止)都从文本文件中读取名字、中间名、姓和分数
String firstname = input.next();
String mi = input.next();
String lastname = input.next();
int Score = input.nextInt();
System.out.println(firstName + " " + mi + " " + lastName + " " + Score);
}
}
}
}
java.net.URL
类可以用来读取web的文件。
注意:URL全大写。
public URL(String spec)
throws MalformedURLException
try{
URL url = new URL("https:/www.google.com/index.html")
}
catch (MalformedURLException ex){
ex.printStackTrace();
}
MalformedURLException
是用来检验URL是否正确的。http://
开头/
为分隔符URL url = new URL("https:/www.google.com/index.html")
Scanner input = new Scanner(url.openStream());
import java.util.Scanner;
import java.net.URL;
public class ReadFileFromURL {
public static void main(String[] args){
System.out.print("Enter a URL: ");
● String URLString = new Scanner(System.in).next();
// 读取URL内容字符串
try {
● URL url = new URL(URLString);
// 以URL内容字符串构造URL对象
int count = 0;
● Scanner input = new Scanner(url.openStream());
// 开放url数据流以读取其中数据。
while(input.hasNext()){
● String line = input.nextLine();
count += line.length();
// 读取每个字符串的长度并相加。
}
System.out.println("The file size is " + count
+ " characters");
// 输出文件长度
}
● catch (java.net.MalformedURLException ex)ex {
System.out.println("Invaild URl");
}
catch (java.io.IOException ex){
System.out.println("I/O Errors: no such file");
}
}
}
父类定义了相关子类中的共同行为,接口可以用于定义类的共同行为。
abstract
修饰符表示。// 抽象类
public abstract class Geo{}
// 抽象方法
public abstract double getArea();
public abstract double getPerimeter();
抽象类和常规类很像,但是不能使用new来创建它的实例。
抽象类只有定义而没有实现,只能被继承。
抽象方法不能包含在非抽象类中。如果抽象父类的子类不能实现父类的所有抽象方法,那么子类也必须定义为抽象的。
虽然不能创造抽象类的实例,但是可以创建它的数组。
Geo[] objects = new Geo[10];
// 然后可以创造一个Geo子类的实例,并将它的引用赋值给数组。
objects[0] = new Circle();
public static final
的,public abstract
,不过java默认可以省略这些修饰符。interface
关键字声明接口。public interface T{
int K = 1;
void p();
}
// 等价于
public interface T{
public static final int K = 1;
public abstract void p();
}
implements
关键字来实现接口。class Chicken extends Animal implements Edible{}
// 在子类中必须实现抽象类和接口中的所有抽象方法。
@Override
public String howToEat(){
return "Chicken: Fry it.";
}
@Override
public String sound(){
return "Chicken: cock-a-doodle-doo";
}
Comparable接口定义了compareTo对象,用来比较对象。
java.util.Arrays.sort(Object[])
方法就可以被使用来进行排序。基础类型的封装类,BigInteger、BigDecimal、Calendar、String、Date等。
Cloneable接口给出了一个可克隆的对象。
浅复制和深复制
一个类可以实现多个接口,但是只能继承一个父类。
其他区别:
public class NewClass extends BasicClass implements
Interface1,Interface2...InterfaceN
public interface Interface1 extends Interface2,Interface3..
注意,继承了子接口的类要实现其上所有类中的构造方法。
// 利用File类来新建对象
FileInputStream input = new FileInputStream(new File("abc.dat"));
// 也可以直接使用文件名来新建对象
FileInputStream input = new FileInputStream("abc.dat");
如果对象名的文件没存在,则创建这个文件。如果对象名的文件存在,那么将会清除文件的内容。如果不想清空内容,可以使用另一个构造方法。
// 在后面增加一个true来在文件中增添内容
FileInputStream input = new FileInputStream("abc.dat", true);
DataInputStream input =
new DataInputStream(new FileInputStream("in.dat"));
DataOutputStream Output =
new DataOutputStream(new FileOutputStream("out.dat"));
import java.io.*;
public class TestDataStream {
public static void main(String[] args) throws IOException{
try(
● DataOutputStream output = new DataOutputStream(new FileOutputStream("temp.dat"));
){
output.writeUTF("John");
output.writeDouble(85.5);
output.writeUTF("Jim");
output.writeDouble(185.5);
output.writeUTF("George");
output.writeDouble(105.25);
}
try(
● DataInputStream input = new DataInputStream(new FileInputStream("temp.dat"));
){
System.out.println(input.readUTF() + " " +input.readDouble());
System.out.println(input.readUTF() + " " +input.readDouble());
System.out.println(input.readUTF() + " " +input.readDouble());
}
}
}
DataInputStream input =
new DataInputStream(new BufferedInputStream(new FileInputStream("fuck.dat")));
递归是程序的一种替换形式,实际上就是不用循环控制的重复。
百度百科:
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
https://www.cnblogs.com/antineutrino/p/3334540.html
开始情况
A:n B:0 C:0
F(n, A, B, C);
他的功能是将n个盘子以某个塔作为辅助,然后将A上的n个盘子移动到C。不用考虑是如何实现的,我们只知道它能完成移动就好!
这个方法的精妙之处在于,他考虑的是这样一种情况:
--------------------------------
考虑已经成功将n-1个盘子移动到B上,此时只要将最大的盘子从A移动到C即可。
fun(n-1,A,C,B)
A:1 B:n-1 C:0
现在最大的盘子到了C上,因为它最大,所以其他盘子在它身上可以随意移动,此时可以无视它,那么场上的盘子数量只有B上的n-1个盘子。这个问题就变成了一个n-1的移动问题,只是开始的柱子变成了B而已。
move(A->C)
A:0 B:n-1 C:1
这时再把B上的n-1个盘子移动到C上
A:0 B:0 C:n
--------------------------------
// 这整个是一次递归过程。
(中间参数是辅助柱子)
func:
if n!=0 then ;预定值
func(n-1, a, c, b) ;将n-1个盘子由a移动到b,以c为辅助柱子
move a[n] to c ;将a上的最后一个盘子移动到c
func(n-1, b, a, c) ;将n-1个盘子由b移动到c,以a为辅助柱子
endif ;完成
如果一个大问题可以分解成无数小一步的子问题,那么方法直接定义为大问题的解决方案!然后找到小问题和大问题之间的联系!
课本上的解决方法:(最后一个参数是辅助柱子)
package demo2;
import java.util.Scanner;
public class TowerOfHanoi {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter number of disks: ");
int n = input.nextInt();
System.out.println("The moves are:");
moveDisks(n, 'A', 'B', 'C');
}
public static void moveDisks(int n, char fromTower, char toTower, char auxTower) {
if (n == 1) {
System.out.println("Move disk" + n + " from " + fromTower + " to " + toTower);
} else {
moveDisks(n - 1, fromTower, auxTower, toTower);
System.out.println("Move disk" + n + " from " + fromTower + " to " + toTower);
moveDisks(n - 2, auxTower, toTower, fromTower);
}
}
}
递归要消耗大量资源,而尾递归就不会。
在Java中谈尾递归:尾递归和垃圾回收的比较。
https://www.cnblogs.com/bellkosmos/p/5280619.html
// 这是尾递归
def tailrecsum(x, running_total=0):
if x == 0:
return running_total
else:
● return tailrecsum(x - 1, running_total + x)
// 这不是尾递归
def recsum(x):
if x == 1:
return x
else:
● return x + recsum(x - 1)
Java进阶篇已经开始更新了
链接:https://www.zybuluo.com/CLSChen/note/1438410