文章目录
Java学习笔记一
1.1 cmd 下执行 Java
-
编译 java 文件
先用“
javac 文件名.java
”命令,生成一个或多个后缀为 class、文件名与类名相同的文件(字节码文件)。javac 命令需要带“java”后缀。
-
执行 class 文件
使用“
java main()所在的类名
”。java 命令无需带“.class”后缀。
以上操作不能执行带 package 的 java 文件,若想执行带 package 的文件,需要使用额外的命令行参数。
1.2 public修饰符
一个 Java 文件中可定义多个类,每个类都会生成一个 class 文件(字节码文件),且 class 文件名与类名相同。
public 修饰的类在每个 Java 文件中最多一个,且类名必须与 Java 文件名相同。
1.3 包(package)
在 IDEA 中,一个 Project 可以有多个 Module,一个Module 下可以有多个 package,一个 package 下可以有多个类。无论是建立 New Project,还是 Empty Project 都会自带一个 Module。可以在 Project Structure 里删除这个 Module。
不同功能的类需要被放到不同的文件夹中。package 的命名采用域名倒置的规则,比如 www.lc.com
下的包可以写成 com.lc.包名
。
1.4 基本数据类型
1.4.1 整型
Java 各整数类型有固定的表数范围和字段长度,不受具体操作系统的影响,以保证 Java 程序的可移植性。
类型 | 占用存储空间 | 表示范围 |
---|---|---|
byte | 1 字节 | -128 ~ 127 |
short | 2 字节 | -215 ~ 215-1 |
int | 4 字节 | -231 ~ 231-1(约21.4亿) |
long | 8 字节 | -263 ~ 263-1 |
定义 long 类型的变量,赋值时需要以"l"或"L"作为后缀。
开发过程中,整型变量通常声明为 int 型。
整型常量默认为 int。
1.4.2 浮点型
浮点型有固定的表数范围和字段长度,不受具体操作系统的影响。
类型 | 占用存储空间 |
---|---|
float | 4 字节 |
double | 8 字节 |
定义 float 类型的变量,赋值时需要以"f"或"F"作为后缀。
float、double 的数据不适合在不容许舍入误差的金融计算领域。如果需要精确数字计算或保留指定位数的精度,需要使用 BigDecimal 类。
浮点型常量默认为 double。
1.4.3 字符型
char 占 2 个字节。值用单引号括起来,例子:char a = 'a';
、char b = '中';
。
char 类型用的是 Unicode 字符集,每个字符对应一个 Unicode 数值(没有涉及具体的编码方式,UTF-8 是一种可变长度编码方式,可以根据字符的不同使用1至4个字节进行编码。),把这个数值强转为 char 类型即可显示这个字符。
char 类型能被赋值 int 类型
常量
。
final int b1= 23320; //少了final,就会过不了编译
char a = b1; //或直接是char a = 23320;
System.out.println(a); //能打印字符
1.4.4 布尔型
boolean 类型数据只有两个值:true、false,无其它
不可以使用 0 或非 0 的整数替代 false 和 true,这点和 C 语言不同,布尔型不能和其他基本数据类型做运算。
1.5 类型转换
1.5.1 自动类型转换
byte ,short,char ==> int ==> long ==> float ==> double
表示范围小的可以转变为表示范围大的,不是看占用存储空间大小。float 能表示的数比 long 还大。
注:只要有 char、byte 、short 参与的运算的结果都是 int。
byte a = 10;
byte b = a + 12;
//会报错,算式里的整数常量 12 默认是 int ,需要用 int 变量接收
//浮点数同理,而浮点数常量默认为 double。
System.out.println('A' + 1); //char 与 int 运算,结果为int,即 66。
System.out.println('A'== 65); //“==”也是运算,涉及自动类型转换,结果为 true。
int a = 'c'; //这里也涉及自动转型
System.out.println(a); //99
1.5.2 强制类型转换
和 C 语言类似,但 String 类型不能通过强制类型转换为基本数据类型,因为 String 不是基本数据类型。
强转改变了字节数,可能导致数值变化。
int b = 10;
byte a = (byte)b;
1.6 break 和 continue
break 语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块,continue 类似。
label1: for(...){ //for1
label2:for(...){ //for2
label3:for(...){ //for3
break label2; //跳出label2后的这个循环,即for2,再执行for1所在的循环。
}
}
}
continue 结束此次循环,然后再次进入所属循环语句的下轮循环。 若上面 break 换成 continue,则是跳出 for2,再进入 for2。
标签不能用在非循环语句的前面。
1.7 Scanner
步骤:
-
导包:
import java.util.Sca nner;
。 -
创建 Scanner 对象:
Scanner scan = new Scanner(System.in);
。 -
next() / nextXxx()
,来获取指定类型的变量,如nextInt()
获取一个 Int 型整数,nextDouble()
获取一个 Double 型浮点数。- 我们把 Scanner 看为 2 个过程,扫描和键入。扫描是去输入缓冲区取数据;键入是从键盘输入数据,以“换行符”作为结束的标志,即按下“Enter”键后才会结束。
- 先扫描,再键入,若缓冲区有数据则无需键入。
next()
和nextLine()
都是读取字符串的方法。next()
和nextLine()
的键入过程相同,扫描过程不同。nextLine()
会读入“空格”,即将“空格”看为字符串的一部分,只把“换行符”作为扫描结束的标志,并且把光标移到“换行符”后。next()
会忽略掉有效字符之前遇到的“空格”以及“换行符”,把有效字符后的“空格”或“换行符”作为扫描结束的标志,并且光标停在结束符之前。nextInt()、nextDouble()
等和next()
扫描过程相同,只有nextLine()
很特殊。
- 这就会出现一个问题,先使用
nextInt()
,光标停在结束符之前,nextLine()
可能会读到空字符串或者带空格的脏数据。解决办法:使用nextInt()
后,先调用nextLine()
把脏数据读走,将光标移到“换行符”后,再用nextLine()
读取需要的数据,也就是使用 2 次nextLine()
。 -
Scanner scanner = new Scanner(System.in); String a = scanner.next(); //输入:123 qweqw String b = scanner.nextLine(); //先扫描缓冲区,发现还有" qweqw",则没有键入过程。 System.out.println(a); //读走"123",剩下" qweqw"以及换行符 System.out.println(b); //“换行符”是扫描结束的标志,则" qweqw" scanner.close();
-
释放资源:
scan.close();
。
1.8 数组
数组本身是引用数据类型,而数组中的元素可以是任何数据类型(基本数据类型或引用数据类型)。
1.8.1 一维数组
声明数组
类型[] 数组名;
,例如int[] arr;
。
Java 中声明数组时,不能指定长度。
未初始化的数组不能直接使用。
初始化
-
静态初始化
初始化的同时赋初值。
- 写法 1:
int[] arr = new int[]{1,2,3,4,5};
- 写法 2:
int[] arr = {1,2,3,4,5};
,这种不能写成int[] arr; arr = {1,2,3,4,5};
,因为编译器识别出不来。
- 写法 1:
-
动态初始化
-
int[] arr = new int[5];
,[] 中指定数组长度,但不赋初值。 -
int n = nums.length; //创建一个和nums相同长度的数组 int[] ans = new int[n];
,在 Java 中,可以将数组长度设置一个变量,只要在初始化之前给这个变量赋值。- 指定长度后,无法修改长度。
- 数组的 length 属性可以得到数组的容量。
- 当使用动态初始化创建数组时,元素值是默认值。
-
1.8.2 Arrays 工具类
java.util.Arrays 类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
- 打印数组
Arrays.toString(arr)
:打印数组所有元素,形式为:[元素1,元素2,元素3...]
。
当 arr 是基本数据类型数组时,直接打印数值。
当 arr 是引用数据类型数组时,每个元素调用该引用类型的toString()
。没有重写toString()
,则打印哈希值。
二维数组的内层元素也是引用类型,调用其的toString()
打印哈希值,若想把内层数组的值一起打印出来,需要用Arrays.deepToString()
。
int[] arr = {1,2,3,4,5};
System.out.println(Arrays.toString(arr));
//[1, 2, 3, 4, 5]
Person person1 = new Person();
Person person2 = new Person();
Person[] arr = new Person[]{person1,person2};
System.out.println(Arrays.toString(arr));
//[Person{name='lc', age=10}, Person{name='lc', age=10}]
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
System.out.println(Arrays.deepToString(arr)); //[[3, 8, 2], [2, 7], [9, 0, 1, 6]]
System.out.println(Arrays.toString(arr)); //[[I@214c265e, [I@448139f0, [I@7cca494b]
- 排序
static void sort(int[] a)
:将 a 数组按照值从小到大进行排序。int[] arr = {1,2,3,43,5}; Arrays.sort(arr); System.out.println(Arrays.toString(arr));//[1,2,3,5,43]
除 boolean 外的基本数据类型,都能排序。
static void sort(Object[] a)
:根据元素的自然顺序,对对象数组按升序进行排序。自然顺序通过重写 Comparable 接口的compareTo(obj o2)
实现。static <T> void sort(T[] a, Comparator<? super T> c)
:根据比较器产生的顺序,对指定对象数组进行升序排序。比较器通过重写 Comparator 接口的compare(obj o1,obj o2)
实现。可以通过修改
compare()
、compareTo()
的实现 ,达到降序排列的目的public class My { public static void main(String[] args) { Integer[] numbers={5,3,9,1,7}; Comparator<Integer> asccomparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1-o2; } }; Arrays.sort(numbers,asccomparator); System.out.println("升序排序后的数组:"); for (Integer number:numbers){ System.out.println(number+""); } }
}
static boolean equals(int[] a, int[] a2)
:比较两个数组的长度、相同下标的元素的数值是否完全相同。int[] a = new int[]{1,2,3,4}; int[] b = new int[]{1,2,3,4}; System.out.println(Arrays.equals(a,b));//true
static boolean equals(Object[] a,Object[] a2)
:比较两个数组的长度、相同下标的对象的内容是否完全相同。Person person = new Person(); Person person1 = new Person(); Person person2 = new Person(); Person[] p = new Person[]{person,person1}; Person[] p1 = new Person[]{person,person2}; System.out.println(Arrays.equals(p,p1)); //根据Person的equals判断
通过该类的
equals()
方法比较对象的内容,若没重写equals()
方法(相当于“==”),则比较的是“是否为同一个对象”。