Java基础1

Java基础1

Getting Started

Anatomy of a Java Program

Java的 函数 我们常常把第一个花括号与函数声明放在一行。但是C,C#常常是另起一行

1
2
3
void sendEmail(){

}

每一个Java程序都必须有一个main函数,也就是主函数

1
2
3
void main(){

}

Java中,这些函数不会单独存在,他们都在类里面。当函数放在类中时,我们称其为类的方法。在Java中,类和方法都应该具有访问修饰符(access modifier),访问修饰符是private,public之类的.

在Java中,我们用不同的方法来命名我们的类和我们的方法。

PascalNamingConvention : 用于类命名。特征就是每个单词首字母大写

camelNamingComvention: 用于方法命名,也就是驼峰命名法

1
2
3
4
5
public class Main{
public void main(){

}
}

Your First Java Program

package com.company 代表着这个类所属的包

这个包下面有Main类,类中有一个静态的main方法

我们现在输出Hello World

在这里使用系统类 System ; System.out 是一个PrintStream 类型,也就是输出字符串的。然后在System.out中我们运用 printIn方法,他是printLine的缩写。点击运行,我们即可看到终端打印Hello World了

1
2
3
4
5
6
7
8
package com.company;
public class Main {

public static void main(String[] args) {
// write your code here
System.out.println("Hello World");
}
}

How Java Code Gets Executed

当我们跑Java程序的时候,是怎么运作的。

在编译步骤中,Intellij 使用Java编译器把代码编译成Java bytecode的形式。编译完成后,Java bytecode可以在Windows ,Mac,Linux或任何有JRE(Java runtime environment)的操作系统上运行。 JRE中各个操作系统都有一个软件叫做JVM(Java Virtual Machine) .JVM 会把Java byte code 转换成 Windows可以理解并架构的Native Code。这就是所谓的 一次编译,到处运行

java有4个版本:Java SE,Java EE,Java ME ,Java Card

Java SE 是Java Standard Edition的缩写,这是Java的核心平台,包含了Java的每一个库

Java EE 是Java Enterprise Edition的缩写,用于构建超大型、分布式系统。它建立在SE之上

Java ME是Java Micro Edition的缩写,这是专门为移动设备设计的Java标准版的子集

Java Card是在智能卡中使用的

Types

Primitive Types

Primitive Types是存储simple value的,也就是下面的八种基本类型

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

byte:

  • byte数据类型是8位、有符号的,以二进制补码表示的整数;
  • 最小值是-128$(-2^7)$;
  • 最大值是127$(2^7-1)$;
  • 默认值是0;
  • byte类型用在大型数组中节约空间,主要代替整数,因为byte变量占用的空间只有int类型的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short数据类型是16位、有符号的以二进制补码表示的整数
  • 最小值是-32768$(-2^{15})$;
  • 最大值是32767 $(2^{15} - 1)$;
  • Short数据类型也可以像byte那样节省空间。一个short变量是int型变量所占空间的二分之一;
  • 默认值是0;
  • 例子:short s = 1000,short r = -20000。

int:

  • int数据类型是32位、有符号的以二进制补码表示的整数;
  • 最小值是-2,147,483,648 $(-2^{31})$;
  • 最大值是2,147,483,647 $(2^{31} - 1)$;
  • 一般地整型变量默认为int类型;
  • 默认值是0;
  • 例子:int a = 100000, int b = -200000。

long:

  • long数据类型是64位、有符号的以二进制补码表示的整数;
  • 最小值是-9,223,372,036,854,775,808 $(-2^{63})$;
  • 最大值是9,223,372,036,854,775,807 $(2^{63} -1)$;
  • 这种类型主要使用在需要比较大整数的系统上;
  • 默认值是0L;
  • 例子:
1
long viewsCount = 3_123_456_789L;

float:

  • float数据类型是单精度、32位、符合IEEE 754标准的浮点数;
  • float在储存大型浮点数组的时候可节省内存空间;
  • 默认值是0.0f;
  • 浮点数不能用来表示精确的值,如货币;
  • 例子:
1
float f1 = 234.5F;

double:

  • double数据类型是双精度、64位、符合IEEE 754标准的浮点数;
  • 浮点数的默认类型为double类型;
  • double类型同样不能表示精确的值,如货币;
  • 默认值是0.0d;
  • 例子:double d1 = 123.4。

boolean:

  • boolean数据类型表示一位的信息;
  • 只有两个取值:true和false;
  • 这种类型只作为一种标志来记录true/false情况;
  • 默认值是false;
  • 例子:boolean one = true。

char:

  • char类型是一个单一的16位Unicode字符;
  • 最小值是’\u0000’(即为0);
  • 最大值是’\uffff’(即为65,535);
  • char数据类型可以储存任何字符;
  • 例子:char letter = ‘A’。

Reference Types

Reference Types是存储复杂的对象的 ,比如说Date类 ,mail message 类

在使用Reference Types 时,我们必须手动分配内存

1
2
3
4
5
6
7
8
9
10
11
12
package com.company;

import java.util.Date;

public class Main {

public static void main(String[] args) {
Date now = new Date();
System.out.println(now);
}
}
// Wed Jul 01 16:33:52 GMT+08:00 2020

Primitive vs Reference Types

Primitive Types 中,我们声明两个变量,让他们相等,那么只是数值上相等,它们的存储地址是不一样的

但是Reference Types ,里面存储的时地址,所以让 point2 = point1之后,point1,point2中存储的有相同的地址。当对point1中修改时,point2也会相应修改。

1
2
3
4
5
6
7
8
9
package com.company;
import java.awt.*;
public class Main {

public static void main(String[] args) {
Point point1 = new Point(1,1);
Point point2 = point1;
}
}

Strings

在java当中,我们String是一个 Reference Type,但是我们使用 String 不需要引入Java的库,也不需要用new来声明(用new也可以,只是简便声明不需要使用new Sring)

我们也可以通过加号直接连接两个字符串。

因为字符串是 Reference Type,所以我们可以通过 . 来使用String类中的方法

区分argumentsparameterparameter可以理解为占位符,只是申请了一段空间的容器。但是arguments是我们传入的值

endsWith()用来判断字符串是否以某一字符串结束的

startsWith()用来判断字符串是否以某一字符串开始的

length()计算字符串的长度

indexOf()计算目标字符串第一个字符在查询字符串中的索引,如果不是该查询字符串的子串,那么返回-1

replace()是替换,前一个参数是被替换的字符串;后一个参数是需要替换进去的字符串

toLowerCase()toUpperCase()是让字符串全部变小写或者大写

trim()是让字符串去掉头尾的空格,这在用户输入一些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.company;
public class Main {

public static void main(String[] args) {
String message = " Hello World" + "!!";
System.out.println(message.endsWith("!!"));
System.out.println(message.startsWith("!!"));
System.out.println(message.length());
System.out.println(message.indexOf("lw"));
System.out.println(message.replace("!","*"));
System.out.println(message.toLowerCase());
System.out.println(message.toUpperCase());
System.out.println(message.trim());
}
}
/*
true
false
15
-1
Hello World**
hello world!!
HELLO WORLD!!
Hello World!!
*/

Escape Sequences 转义序列

双引号的转义 就是 \"

反斜杠的转义就是 \\

换行的转义就是 \n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.company;
public class Main {

public static void main(String[] args) {
System.out.println("Hello World \"Jason\" ");
System.out.println("c\\windows\\...");
System.out.println("c:\nWindows\\...");
}
}
/*
Hello World "Jason"
c\windows\...
c:
Windows\...
*/

Arrays

用繁琐且老旧的语法来声明一个数组的语法是这样的:

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
System.out.println(Arrays.toString(numbers));
}
}

当我们提前知道了数组中的元素的时候,我们可以更简单的声明一个数组

用花括号声明即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) {
int[] numbers = {2,3,4,5,1};
System.out.println(numbers.length);
System.out.println(Arrays.toString(numbers));
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
/*
5
[2, 3, 4, 5, 1]
[1, 2, 3, 4, 5]
*/

我们不能直接 System.out.printIn(number) 因为这样java引擎会根据每个数字存储的地址计算得出一个我们看不懂的字符串。所以需要System.out.println(Arrays.toString(numbers));

Multi-dimensional Arrays

我们可以定义多维数组,但是多维数组需要deepToString()而不是 toString()才能正常打印

1
2
3
4
5
public static void main(String[] args) {
int [][][] numbers = new int[2][3][5];
numbers [0][0][1] = 1;
System.out.println(Arrays.deepToString(numbers));
}
1
2
3
4
public static void main(String[] args) {
int [][] numbers = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(numbers));
}

Constants 常量(final关键词)

我们想定义 pi为常量,所以我们希望它一经申明就不能再改变,我们需要用final来声明一个常量。常量的所有字母需要大写。

1
2
3
4
5
6
public class Main {

public static void main(String[] args) {
final float PI = 3.14F;
}
}

此外,final还可以用来修室类和方法。浅谈Java中的final关键字 - 平凡希 - 博客园 (cnblogs.com)

当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。

如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。即父类的final方法是不能被子类所覆盖的,也就是说子类是不能够存在和父类一模一样的方法的。

Arithmetic Expressions

和C++一样,不讲了

Order of Operations

和C++一样,不讲了

Casting

java中的类型转换

1
2
3
short x = 1;
int y = x+2;
System.out.println(y);

我们这样会做一个隐式类型转换。short是短整型,int是整型。int中可以存储所有short变量当中的值

在java中,是这样操作隐式类型转换的 :在 int y = x+2 这句话中,java看见x,会在内存中某个地方申明一个匿名变量,那个匿名变量是整数,然后java将x的值复制到那个匿名变量中。再执行加法

1
2
3
double x = 1.1;
double y = x+2;
System.out.println(y);

在整型、浮点数之间转换,java也会按照这个规则。 首先会把2 转换为2.0 ,其次执行加法

byte>short>int>long>float>double java中的数据类型可以根据这个链转换。如果不丢失数据的话,都会发生隐式转换。

我们也可以进行强制类型转换,这时候会丢失一些数据

1
2
3
4
double x = 1.1;
int y = (int)x +1;
System.out.println(y);
//结果为2

现在,我们想把string 转为数字,无论用隐式转换还是显示转换都无法达成。需要引用一个类

Short.parseShort()Integer.parseInt()Double.parseDouble() 等来把字符串转换成整数、浮点数

注意: 如果 String x = "1.1" 那么转换成 整数的时候,就会发生报错

1
2
3
String x = "1";
int y = Short.parseShort(x)+2 ;
System.out.println(y);

The Math Class

1
2
3
4
5
int result = Math.round(1.1F);
int result2 = (int) Math.ceil(1.1F);
int result3 = (int) Math.max(1,2);
int result4 = (int) Math.min(1,2);
int result5 = (int) Math.random();

注意,我们不能 这样来得到一个0-100的随机整数:int result = (int) Math.random()*100; 因为Math.random()产生一个0-1的小数,int转换之后变成0了,0*100 还是等于0,所以我们必须要把整个表达式包裹: int result = (int) (Math.random()*100);

Formatting Numbers

注意:NumberFormat是一个抽象类,无法实例化,我们不能直接 NumberFormat currency = new NumberFormat()

我们需要用到NumberFormat这个类。其中getCurrencyInstance是把数字转换成钱币的格式,getPercentInstance则是把数字转换成百分比的形式。

我们可以简单的使用NumberFormat.getCurrencyInstance().format() 来格式化字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.company;
import java.text.NumberFormat;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
NumberFormat currency = NumberFormat.getCurrencyInstance();
String result = currency.format(1234567.891);
System.out.println(result);
NumberFormat percent = NumberFormat.getPercentInstance();
String result2 = percent.format(0.2);
System.out.println(result2);
String result3 = NumberFormat.getCurrencyInstance().format(1213.39);
System.out.println(result3);
}
}

Reading Input

要读取字符串或者数字,我们需要用到scanner

首先新建一个 Scanner对象,我们要确定信息是从终端获取的还是从文件当中获取的。我们这里是从终端获取的,所以选择 System.in

然后用scanner.nextByte()读取一个byte 或者 scanner.nextline()是读取一行信息,以此类推,有
nextBoolean() ,nextDouble() ,nextFloat()等等

因为System.out.println();打印一行信息, 我们希望 是 Age: 后输入年龄,不用换行。所以使用 System.out.print()

1
2
3
4
5
6
7
8
9
10
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Age: ");
byte age = scanner.nextByte();
System.out.println("Your age is "+age);
}
}

Project- Mortgage Calculator 按揭

等额本息公式: $P = L[c(1+c)^n]/[(1+c)^n-1] $

每月还款金额 = [贷款本金×月利率×(1+月利率)\^还款月数]÷[(1+月利率)\^还款月数-1]

其中 L 代表 principal,即本金

c 代表 monthly Interest ,月利率

n 代表 月数

相对于等额本金还款法 的劣势在于支出利息较多,还款初期利息占每月供款的大部分,随本金逐渐返还供款中本金比重增加。但该方法每月的还款额固定,可以有计划地控制家庭收入的支出,也便于每个家庭根据自己的收入情况,确定还贷能力。

最终计算得到的 Mortage就是每月需要支付的按揭金额

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.company;

import java.text.NumberFormat;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
final byte MONTHS_IN_YEAR = 12;
final byte PERCENT = 100;

Scanner scanner = new Scanner(System.in);

System.out.print("Principal: ");
int principal = scanner.nextInt();

System.out.print("Annual Interest Rate: ");
float annualInterest = scanner.nextFloat();
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

System.out.print("Period (Years): ");
byte years = scanner.nextByte();
int numberOfPayments = years * MONTHS_IN_YEAR;

double mortgage = principal
* (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
/ (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);

String mortgageFormatted =
NumberFormat.getCurrencyInstance().format(mortgage);
System.out.println("Mortgage: " + mortgageFormatted);
}
}

Control Flow

Comparison Operators

和C++一样

Logical Operators

在C中布尔变量用bool声明,但是在java中用 boolean声明,其他一样

||, &&,! 和C++一样

If Statements

和C++一样

The Ternary Operator

也就是 ?: 运算符,和C++一样

Switch Statements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) {
String role = "admin";
switch (role){
case "admin":
System.out.println("You're an admin");
break;
case "moderator":
System.out.println("You're a moderator");
break;
default:
System.out.println("You're a guest");
}
}
}

Exercise- FizzBuzz

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.company;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Number : ");
int x = scanner.nextInt();
if(x%15==0)
System.out.println("FizzBuzz");
else if(x%3==0)
System.out.println("Buzz");
else if(x%5==0)
System.out.println("Fizz");
else
System.out.println(x);
}
}

For Loops

和C++一样

While Loops

和C++一样

Do..While Loops

和C++一样

Break and Continue Statements

和C++一样

For-Each Loop

1
2
3
4
5
6
7
8
9
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String[] fruits = {"Apple","Mango","Orange"};
for(String i:fruits)
System.out.println(i);
}
}

还是和C++一样

Project- Mortgage Calculator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.company;

import java.text.NumberFormat;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
final byte MONTHS_IN_YEAR = 12;
final byte PERCENT = 100;

int principal = 0;
float monthlyInterest = 0;
int numberOfPayments = 0;

Scanner scanner = new Scanner(System.in);

while (true) {
System.out.print("Principal: ");
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1000 and 1000000");
}

while (true) {
System.out.print("Annual Interest Rate: ");
float annualInterest = scanner.nextFloat();
if (annualInterest >= 1 && annualInterest <= 30) {
monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;
break;
}
System.out.println("Enter a value between 1 and 30");
}

while (true) {
System.out.print("Period (Years): ");
byte years = scanner.nextByte();
if (years >= 1 && years <= 30) {
numberOfPayments = years * MONTHS_IN_YEAR;
break;
}
System.out.println("Enter a value between 1 and 30.");
}

double mortgage = principal
* (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
/ (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);

String mortgageFormatted =
NumberFormat.getCurrencyInstance().format(mortgage);
System.out.println("Mortgage: " + mortgageFormatted);
}
}

Clean Coding

对上面的代码进行优化、重构

Creating Methods 新建方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.company;

public class Main {
public static void main(String[] args) {
greetUser("Jason","Ball");
greetUser2("John","Snow");
}

public static void greetUser(String firstName,String lastName){
System.out.println("Hello "+firstName+" "+lastName);
}
public static String greetUser2(String firstName,String lastName){
return "Hello "+firstName+" "+lastName;
}
}

Extracting Methods

就像上面写的简单的方法一样,现在我们把计算Mortage写成一个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.company;

import java.text.NumberFormat;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {


int principal = 0;
float annualInterest = 0;
byte years = 0;

Scanner scanner = new Scanner(System.in);

while (true) {
System.out.print("Principal: ");
principal = scanner.nextInt();
if (principal >= 1000 && principal <= 1_000_000)
break;
System.out.println("Enter a value between 1000 and 1000000");
}

while (true) {
System.out.print("Annual Interest Rate: ");
annualInterest = scanner.nextFloat();
if (annualInterest >= 1 && annualInterest <= 30)
break;
System.out.println("Enter a value between 1 and 30");
}

while (true) {
System.out.print("Period (Years): ");
years = scanner.nextByte();
if (years >= 1 && years <= 30)
break;
System.out.println("Enter a value between 1 and 30.");
}
double mortgage = calculateMortage(principal,annualInterest,years);
String mortgageFormatted =
NumberFormat.getCurrencyInstance().format(mortgage);
System.out.println("Mortgage: " + mortgageFormatted);
}

public static double calculateMortage(
int principal,
float annualInterest,
byte years){
final byte MONTHS_IN_YEAR = 12;
final byte PERCENT = 100;
short numberOfPayments = (short)(years * MONTHS_IN_YEAR);
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

return principal
* (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
/ (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);
}
}

Refactoring Repetitive Patterns

然后,我们继续把输入数字的语句抽象出来成为一个函数,readByte,readInt,readFloat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.company;

import java.text.NumberFormat;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);
int principal = (int) readNumber("Principal: ",1000,1000000);
float annualInterest = (float)readNumber("Annual Interest Rate: ",1,30);
byte years = (byte)readNumber("Period (Years): ",1,30);

double mortgage = calculateMortage(principal,annualInterest,years);
String mortgageFormatted =
NumberFormat.getCurrencyInstance().format(mortgage);
System.out.println("Mortgage: " + mortgageFormatted);
}

public static double readNumber(String prompt,double min,double max){
Scanner scanner = new Scanner(System.in);
double value;
while (true) {
System.out.print(prompt);
value = scanner.nextInt();
if (value >= min && value <= max)
break;
System.out.println("Enter a value between "+min+" and "+max);
}
return value;
}
public static double calculateMortage(
int principal,
float annualInterest,
byte years){
final byte MONTHS_IN_YEAR = 12;
final byte PERCENT = 100;
short numberOfPayments = (short)(years * MONTHS_IN_YEAR);
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

return principal
* (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
/ (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);
}
}

Project- Payment Schedule

计算每期付款后剩下需要还款余额

公式:$B =L[(1+c)^n-(1+c)^p]/[(1+c)^n-1]$

B 代表 Balance,即需要还款的余额

p代表当前还款进行到第几个月

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.company;

import java.text.NumberFormat;
import java.util.Scanner;

public class Main {
final static byte MONTHS_IN_YEAR = 12;
final static byte PERCENT = 100;

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);
int principal = (int) readNumber("Principal: ",1000,1000000);
float annualInterest = (float)readNumber("Annual Interest Rate: ",1,30);
byte years = (byte)readNumber("Period (Years): ",1,30);

double mortgage = calculateMortage(principal,annualInterest,years);
String mortgageFormatted =
NumberFormat.getCurrencyInstance().format(mortgage);
System.out.println();
System.out.println("MORTAGE");
System.out.println("------");
System.out.println("Mortgage: " + mortgageFormatted);

System.out.println();
System.out.println("PAYMENT SCHEDULE");
System.out.println("------");
for(short month = 1;month<= years*MONTHS_IN_YEAR;month++){
double balance = calculateBalance(principal,annualInterest,years,month);
System.out.println(NumberFormat.getCurrencyInstance().format(balance));
}

}
// readNumber 是读取信息并做安全性判断的函数
public static double readNumber(String prompt,double min,double max){
Scanner scanner = new Scanner(System.in);
double value;
while (true) {
System.out.print(prompt);
value = scanner.nextInt();
if (value >= min && value <= max)
break;
System.out.println("Enter a value between "+min+" and "+max);
}
return value;
}
// calculateBalance 是计算当前仍需还款余额的函数
public static double calculateBalance(
int principal,
float annualInterest,
byte years,
short numberOfPaymentMade) {

short numberOfPayments = (short)(years * MONTHS_IN_YEAR);
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

double balance = principal*(Math.pow(1+monthlyInterest,numberOfPayments)-Math.pow(1+monthlyInterest,numberOfPaymentMade))/(Math.pow(1+monthlyInterest,numberOfPayments)-1);
return balance;
}
// calculateMortage 是计算每月需要还款的金额的函数
public static double calculateMortage(
int principal,
float annualInterest,
byte years){

short numberOfPayments = (short)(years * MONTHS_IN_YEAR);
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

return principal
* (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
/ (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);
}
}

我们可以利用idea自带的 Refactory->Extract->Method来自动生成方法十分方便。

Debugging and Deploying Applications

Types of Errors

Compile-time Errors Idea可以帮我们提示

Run-time Errors 可以通过Debugger来调试

Debugging Java Applications

https://www.bilibili.com/video/BV19J411t7dD?p=15

Packaging Java Applications

https://www.bilibili.com/video/BV19J411t7dD?p=16

-------------本文结束,感谢您的阅读-------------