本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2022-07-07
JDK = JRE + Java开发工具(javac, java, javadoc)
JRE = JVM + Java核心类库
javadoc -d docDirName -author -version demo01.java
在一个java源文件中可以声明多个class,但是只能有一个类声明为public,且这个类的类名需要与该.java文件名一致
程序的入口是main()方法,除入参外,格式是固定的。
public class Hello {
public static void main(string[] args) {
// ...
}
}
public是装饰符 static是声明为静态方法 void说明main是没有返回值的
基本数据类型:整数型(byte/short/int/long)、浮点型(float/double)、字符(char)、布尔型(boolean)
引用数据类型:类(class)、接口(interface)、数组([] array)
字符串是一个类类型。
byte: 1字节 = 8bit,表数范围(-128, 127)
short: 2字节 (-2^15, 2^15-1)
int: 4字节 (-2^31, 2^31-1)
long: 8字节 (-2^63, 2^63-1)
声明long类型的变量必须以l
或L
结尾。
单精度float:4字节 表数范围(-3.403E38,3.403E38)
双精度double: 8字节 表数范围(-1.798E308, 1.798E308)
单精度可以精确到7位有效数字,很多情况下,精度很难满足需求,double是双精度,精度是float的两倍,通常采用此类型, Java中的浮点型常量默认为double型,声明float变量,后面需要以f
或F
结尾。
char: 2字节,使用单引号定义,只能有一个字符
char c = '中';
// 转义字符 换行符
char c2 = '\n';
// 制表符
char c3 = '\t';
// unicode
char c4 = '\u0043'
boolean flag = true;
当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型,此时的容量大小指的是,表示数的范围的大和小。比如 float容量要大于long的容量
byte/short/char -> int -> long -> float -> double
byte b1 = 2;
int i1 = 2;
int i2 = b1 + i1;
// 字节小的和字节大的类型做运算,应该使用字符大的类型去接收结果。
float f = b1 + i1; // 这样也可以,但是会变成浮点型 f为 4.0
char c1 = 'a';
int i2 = 10;
int r = c1 + i2; // 107, 字符串以Unicode码对应的数字与整数型进行运算
// 当byte、char、short三种类型的变量作运算时,结果为int类型
char c2 = 'b'
short s = 11;
int r1 = c2 + s;
byte b2 = 12;
byte b3 = 13;
int r2 = b2 + b3; // 即使是byte同种类型作运算,结果为int型
double d1 = 12.9;
int i1 = (int)d1; // 强转,会损失精度 i1的结果是12
int i2 = 128;
byte b = (byte)i2; // b会是-128
强制类型可能为出现精度损失。
long l = 123123; // 没加l为默认当做int类型
byte b = 12;
byte b1 = b + 1; // error 整数型常量1的默认类型是int型
int i = b + 1;
String属于引用数据类型。
String s1 = "hello wrold";
char h = s1.charAt(0); // 获取s1下标为0的字符
String s2 = "a";
String s3 = "";
char c = ''; // char类型不能是空字符
String info = s1 + s2; // 字符串用+ 是连接运算
boolean b = true;
String r = s2 + b; // atrue String类型
String 可以和8种基本数据类型做运算,且运算只能是连接运算,结果仍然是String类型。
逻辑运算符&
、|
、!
、^
操作的都是boolean类型的变量。
短路运算符 &&
和 ||
与逻辑运算符 &
和 |
的区别是:
// & 与 && 的运算结果相同
// 当符号左边是true时,二者都会执行符号右边的运算
// 当符号左边是false时,&继续执行符号右边的运算,而&&不再执行符号右边的运算
boolean b1 = false;
int num1 = 10;
if (b1 & (num1++ > 0)) {
System.out.println("1");
} else {
System.out.println("2");
}
System.out.println(num1); // 11
boolean b2 = false;
int num2 = 10;
if (b2 && (num2++ > 0)) {
System.out.println("1");
} else {
System.out.println("2");
}
System.out.println(num2); // 10
&
、|
、~
(取反)、^
,如果操作的都是数字类型,就是位运算符,最终操作的是它们的二进制数的运算,结果也是数字。
对应的还有
>>
(右移):在一定范围里,每向右移N位相当于除以一个2的n次方,最高位的补位根据之前的符号位进行是0补0,是1补1。
<<
(左移):在一定范围例,每向右移N位相当于乘以一个2的n次方,因为正数可能会移成一个负数。后面一律补0。
>>>
(无符号右移)
<<<
(无符号左移)
// 1.导包
import java.util.Scanner;
public class demo01 {
public static void main(String[] args) {
// 2.实例化 Scanner 对象
Scanner scan = new Scanner(System.in);
System.out.print("输入一个数字:");
// 3.调用nextInt()接收键盘输入的数字
int num = scan.nextInt();
System.out.println("你输入的数字是: " + num);
// Scanner.next() 接收字符串输入
// Scanner.nextDouble() 接收浮点型输入
// Scanner.nextBoolean() 接收布尔型输入
// 当输入的类型与要求的类型不匹配时,会报异常。
}
}
// 求100以内的质数
public class demo02 {
public static void main(String[] args) {
// 获取当前时间的毫秒数
long start = System.currentTimeMillis();
for (int i = 2; i <= 100; i++) {
boolean flag = true;
// 取开方就可以
// 因为 比如非质数36 它的因数 2 * 18 / 3 * 12 / 4 * 9 / 6 * 6 / 9 * 4 / ...
// 能够被除开的是一对一对的,所以检查前半部分就够了 是否被2,3,4,6除尽 这个6就是开方而来
// 这一对一对就以其开方作为中间线,中间线之后的就是前面的调换乘数位置而已 所以只检查前半部分即可
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
flag = false;
break;
}
}
if (flag == true) {
System.out.println(i);
}
}
long end = System.currentTimeMillis();
System.out.println("所花费的时间为: " + (end - start) + " ms");
}
}
跳出循环结构
public class demo03 {
public static void main(String[] args) {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 10; j++) {
if (j % 4 == 0) {
break;
}
System.out.print(j); // 输出123 输出4遍 break默认跳出距离此关键字最近的一层循环结构
}
System.out.println();
}
System.out.println("跳转指定的循环结构");
label:for (int m = 1; m <= 4; m++) {
for (int n = 1; n <= 10; n++) {
if (n % 4 == 0) {
break label; // 结束指定标识的一层循环结构
}
System.out.print(n); // 输出123 输出1遍
}
System.out.println();
}
}
}
continue
也是一样,可以结束指定标识的一层循环结构的当次循环。
demo04FamilyAccount.java
public class demo04FamilyAccount {
public static void main(String[] args) {
boolean isFlag = true;
String details = ""; // 记录用户的收入和支出的详情
int balance = 10000; // 初始金额
while (isFlag) {
System.out.println("---------------------家庭收支记账软件---------------------");
System.out.println(" 1 收支明细 ");
System.out.println(" 2 登记收入 ");
System.out.println(" 3 登记支出 ");
System.out.println(" 4 退 出\n ");
System.out.print(" 请选择(1-4): ");
// 获取用户的选择
char selection = demo04Utility.readMenuSelection();
switch (selection) {
case '1':
System.out.println("---------------------当前收支明细记录---------------------");
System.out.println("收支\t\t账户金额\t\t收支金额\t\t说 明\n");
System.out.print(details);
System.out.println("-------------------------------------------------------");
break;
case '2':
System.out.print("本次收入金额:");
int money = demo04Utility.readNumber();
System.out.print("本次收入说明:");
String info = demo04Utility.readString();
balance += money;
details += "收入\t\t" + balance + "\t\t" + money + "\t\t\t" + info + "\n";
System.out.println("------------------------登记完成------------------------");
break;
case '3':
System.out.print("本次支出金额:");
int money2 = demo04Utility.readNumber();
System.out.print("本次支出说明:");
String info2 = demo04Utility.readString();
if (balance >= money2) {
balance -= money2;
details += "支出\t\t" + balance + "\t\t" + money2 + "\t\t\t" + info2 + "\n";
} else {
System.out.println("支出超出账户额度,支付失败");
}
System.out.println("------------------------登记完成------------------------");
break;
case '4':
System.out.print("确认是否退出(Y/N): ");
char isExit = demo04Utility.readConfirmSelection();
if (isExit == 'Y') {
isFlag = false; // 改变变量,结束循环,程序结束
}
break;
}
}
}
}
demo04Utility.java
import java.util.Scanner;
public class demo04Utility {
private static final Scanner scanner = new Scanner(System.in);
/**
* 用于界面菜单的选择 该方法读取键盘,如果用户键入1-4中的任意字符,则方法返回
* @return 返回为用户键入的字符
*/
public static char readMenuSelection() {
char c;
// 使用一个"死"循环 是因为用户可能会有无数次输入都不符合预期,不符合预期就重新开始 直到用户输入期望值
for (;;) {
String str = readKeyBoard(1);
c = str.charAt(0);
if (c != '1' && c != '2' && c != '3' && c != '4') {
System.out.print("选择错误,请重新输入:");
} else {
break;
}
}
return c;
}
/**
* 用于收入和支出金额的输入 该方法读取键盘 该方法从键盘读取一个不超过4位长度的整数
* @return 返回用户输入的数字
*/
public static int readNumber() {
int n;
for (;;) {
String str = readKeyBoard(4);
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.print("数字输入错误, 请重新输入:");
}
}
return n;
}
/**
* 用于收入和支出说明的输入 从键盘读取一个不超过8位长度的字符串
* @return 返回用户输入的相关收入和支出的说明
*/
public static String readString() {
return readKeyBoard(8);
}
/**
* 用于确认选择的输入,该方法从键盘读取Y或N,并将其作为返回值
* @return Y/N
*/
public static char readConfirmSelection() {
char c;
for (;;) {
String str = readKeyBoard(1).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
/**
* 封装读取键盘输入方法,当输入不满足期望时可重新输入 while(scanner.hasNext())
* @param limit 对输入长度的限制
* @return 输入的信息
*/
private static String readKeyBoard(int limit) {
String line = "";
while (scanner.hasNext()) {
line = scanner.nextLine();
int lineLen = line.length();
if (lineLen < 1 || lineLen > limit) {
System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}
public class ArrayTest {
public static void main(String[] args) {
// 1. 初始化
// 静态初始化 数组初始化和数组元素的赋值操作同时进行
int[] ids = new int[]{1001, 1002, 1003, 1004};
// 可以类型推断
int[] ids2 = {3, 4, 5, 6};
// 动态初始化 数组初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
// 数组一旦初始化完成,其长度就确定了
// 2. 调用数组指定位置的元素
names[0] = "Anna";
names[1] = "Bob";
// 3. 获取数组的长度 需要注意的是,String获取长度是length()方法,而数组获取长度的是length属性
System.out.println(names.length);
// 4. 如何遍历数组
for(int i = 0; i < names.length; i++) {
System.out.println(names[i]); // 未赋值的默认是null
}
// 4.1 简写
for (String name : names) {
System.out.println(name);
}
char[] arr = new char[4];
for(int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
// tips
System.out.println("char数组的默认值与0是相等的");
}
}
long[] bArr = new long[2];
System.out.println(bArr[0]);
}
}
// 数组元素的未初始化的默认值
// 基本数据类型
// - int/short/long/byte数组:默认为0
// - float/double数组:默认为0.0
// - char数组:默认为ASCII码为0(即'\u0000')的值 => NUL 字符是空
// - boolean数组:默认为false
// 引用数据类型
// - String:默认为null
public class ArrayTest2 {
public static void main(String[] args) {
int [][] arr = new int[][]{{1, 2}, {3, 4}, {5, 6}};
String [][] strArr = new String[3][2];
String [][] strArr2 = new String[3][];
int[] arr2[] = new int[3][2];
// 等同于 int[][] arr2 = new int[3, 2]
// 一维数组也可以这样声明
String names[] = new String[3];
int[][] arr3 = new int[4][3];
System.out.println(arr3[0]); // [I@3af49f1c 地址
System.out.println(arr3[0][0]); // 0
float[][] arr4 = new float[4][3];
System.out.println(arr4[0]); // [F@19469ea2
System.out.println(arr4[0][0]); // 0.0
double[][] arr5 = new double[4][]; // 二维数组初始化时只指定外层的个数,说明创建了一个数组arr5包含4个空数组
System.out.println(arr5[0]); // null
}
}
public class YangHuiTest {
public static void main(String[] args) {
int[][] arr = new int[10][];
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
for (int j = 0; j < arr[i].length; j++) {
if (j == 0 || (j == arr[i].length - 1)) {
arr[i][j] = 1;
} else {
arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
}
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
public class HuiXingTest {
public static void main(String[] args) {
int[][] arr = new int[9][8];
String direction = "right";
int i = 0;
int j = 0;
int maxI = arr.length - 1;
int maxJ = arr[0].length - 1;
label:for (; i < arr.length; ) {
for (; j < arr[i].length; ) {
if (i == 0 && j == 0) {
arr[i][j] = 1;
j++;
continue;
}
switch (direction) {
case "right":
arr[i][j] = arr[i][j-1]+1;
break;
case "down":
arr[i][j] = arr[i-1][j]+1;
break;
case "left":
arr[i][j] = arr[i][j+1]+1;
break;
case "up":
arr[i][j] = arr[i+1][j]+1;
break;
}
if (arr[i][j] == ((maxI + 1) * (maxJ + 1))) {
break label;
}
if (direction == "right" && j == maxJ - i) {
direction = "down";
}
if (direction == "down" && i == maxI - (maxJ - j)) {
direction = "left";
}
if (direction == "left" && j == maxI - i) {
direction = "up";
}
if (direction == "up" && i == j + 1) {
direction = "right";
}
switch (direction) {
case "right":
j++;
break;
case "down":
i++;
break;
case "left":
j--;
break;
case "up":
i--;
break;
}
}
}
for (int k = 0; k < arr.length; k++) {
for (int m = 0; m < arr[k].length; m++) {
int num = arr[k][m];
if (num < 10) {
System.out.print("0" + arr[k][m] + " ");
} else {
System.out.print(arr[k][m] + " ");
}
}
System.out.println();
}
}
}
常用工具函数
public class ArraysTest {
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4};
int[] arr2 = new int[]{2, 1, 3, 4};
// 1. Arrays.equals() 判断两个数组是否相等
boolean b1 = Arrays.equals(arr1, arr2);
System.out.println(b1); // false
// 2. Arrays.toString() 输出数组信息
String s1 = Arrays.toString(arr1);
System.out.println(s1); // "[1, 2, 3, 4]"
// 3. Arrays.fill(int[] a, int val) 将指定的值填充到数组之中
int[] arr3 = new int[4];
Arrays.fill(arr3, 1);
System.out.println(Arrays.toString(arr3)); // "[1, 1, 1, 1]"
// 4. Arrays.sort() 对数组进行排序
int[] arr4 = new int[]{1, 3, 2, 4, 5};
Arrays.sort(arr4);
System.out.println(Arrays.toString(arr4)); // "[1, 2, 3, 4, 5]"
// 5. Arrays.binarySearch 对数组进行二分查找,需要数组是有序的。
int[] arr5 = new int[]{11, 22, 33, 45, 66, 78, 99};
int index = Arrays.binarySearch(arr5, 99);
System.out.println(index); // 6 如果返回的是一个负数就是未找到,具体是负多少不确定
}
}