第1章 Java程序设计概述
- Java三大特性:封装、继承、多态。
- 封装:就是指对对象中的属性进行了私有化,只提供了两个公共的set和get方法,设置属性和获取属性值。提供数据的安全性。
- 继承:就是指一个类不仅拥有已有类的属性和方法,还可以拥有自己的属性和方法。注意:子类并不能真正继承父类的构造,但可以调用。
- 多态:就是指重载和重写。重载:指一个类中有两个同名不同参的方法。重写:指子类中拥有与父类同名同参的方法。
- 在Java的web浏览器中运行的Java程序称为applet。(该技术已经过时,很少使用)
第2章 Java程序设计环境
- JDK与JRE的联系与区别:
- JDK,Java Development Kit 的缩写,Java开发工具包。
- JRE,Java Runtime Environment的缩写,Java运行环境。
- jdk包含了jre、编译器等其它工具。jdk是开发者需要的环境,而jre则是专门为不需要编译器的用户而提供。
- JDK的安装与设置,请参考https://www.runoob.com/java/java-environment-setup.html
第3章 Java的基本程序设计结构
3.1 一个简单的Java一个用程序
1 | public class FirstSample { |
public——访问修饰符,用于定义访问权限。
class——关键字。
FirstSample——类名(自己定义)。
static——关键字。
void——关键字,表明无返回参数。
main——方法名,可自定义,在该处的“main”为主方法。
System.out.println();——用于输出内容到控制台。
命名规范:
- 类名以大写字母开头。
- 包名、方法名以小写字母开头。
- 所有的命名都遵循“驼峰命名法”。
3.2 注释
三种注释方式:
- 单行注释,使用“//”。eclipse中的快捷键:ctrl+/。
- 多行注释,使用“/* */”。eclipse中的快捷键:ctrl+shift+/。
- JavaDoc注释,可生成API文档,使用“/** */”。eclipse中的快捷键:打出“/**”,然后回车即可。
3.3 数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
整型:
- byte(1字节)
- short (2字节)
- int(4字节)(最常用)
- long(8字节),长整型数值会有后缀“L”或“l”(建议使用“L”,不易混淆)。十六进制数值有前缀“0x”或“0X”,八进制数值也有前缀,但不建议使用八进制,容易出问题。
注意:Java中没有任何无符号(unsigned)形式的int、short、long、byte类型。
浮点类型:
- float(4字节),单精度数值有后缀“f”或“F”。
- double(8字节)(最常用),双精度数值有后缀“d”或“D”。
- 没有后缀的浮点数值(如3.14)默认为double类型。
- 特殊浮点数值:
- NaN(not a number,不是一个数字),5/0则会出现该结果。
double z = Double.NaN;
- 正无穷大,正整数除以0结果为正无穷大。
double x = Double.POSITIVE_INFINITY;
- 负无穷大。
double y = Double.NEGATIVE_INFINITY;
- NaN(not a number,不是一个数字),5/0则会出现该结果。
char类型
- char类型变量或字面量值需要2字节的空间。
- char类型的字面量值要用单引号括起来。
- 特殊字符的转义序列不在此做过多赘述。
boolean类型
boolean(布尔)类型有两个值:false和true,用于判定逻辑条件。整型值和布尔值之间不能进行相互转换。
3.4 变量
变量声明及初始化
1
2
3
4
5
6
7
8
9//变量声明
double salary;
int vacationDays;
//变量初始化
salary = 3.14;
vacationDays = 12;
//也可在声明变量的同时进行初始化
double salary = 3.14;
int vacationDays = 12;Java中,不区分变量的声明与定义。
常量
在Java中,利用关键字final指示常量。关键字final表示这个变量只能被赋值一次,一旦被赋值就不能再更改。常量名使用全大写。
若希望某个常量在一个类的多个方法中使用,通常将这些常量定义为类常量,使用 static final 修饰。类常量的定义位于main方法的外部。
1
2
3
4
5
6
7
8
9
10
11public class FirstSample {
//类常量的定义位于main方法的外部。
public static final double PI = 3.14;
public static void main(String[] args) {
System.out.println("Hello Java!!!");
}
}
3.5 运算符
算数运算符:+、-、*、/、%(加、减、乘、除、取余)
- 当参与运算的两个操作数精度不同时,低精度操作数会自动转换成高精度参与运算。
- 取余操作只针对整型数值。
- 整数被0除会产生异常,而浮点数被0除将会得到无穷大或NaN。
数学函数与常量
1
2
3
4
5//求平方根
double x = Math.sqrt(4);
//幂运算
double y = Math.pow(3, 3);- Math类里面的方法均为静态方法。
- 可以通过在数学方法名和变量名前添加前缀“Math”来调用相应方法,也可以在源文件引入相关的包:
import static java.lang.Math.*;
数值类型之间的转换
自动类型转换:
小类型向大类型转换:
- 小类型向大类型转换会自动完成,由JVM负责。也称为”隐式类型转换“。
- 自动转换规则:符号位自动扩展,负数补1,正数补0。
- 自动类型转换包含以下情况:
- byte->short->int->long->float->double
- int和char类型的数据在某些情况下可以相互转换
- 整数到浮点数转换会损失精确度。
强制类型转换:
大类型向小类型转换:
- 强制类型转换,简称强转,也称为“显式类型转换”。
- 强转时,要注意边界数风险问题。
- 强转时,可能发生数据丢失或错误问题。
自增与自减运算符
- n++:先赋值,再自增1
- n–:先赋值,再自减1
- ++n:先自增1,再赋值
- –n:先自减1,再赋值
关系运算符
Java关系运算的种类:
==
!=
>
<
>=
<=
- 关系运算的最后结果为true或false。
逻辑运算符
逻辑运算是在关系运算基础之上的运算,能处理更复杂的问题。运算的结果为true或false。
Java逻辑运算的种类:
运算种类 运算符号 运算表达式 与运算(长路运算) & 关系运算1 & 关系运算2 与运算(短路运算) && 关系运算1 && 关系运算2 或运算(长路运算) | 关系运算1 | 关系运算2 或运算(短路运算) || 关系运算1 || 关系运算2 非运算 ! !(关系运算) 长路运算与短路运算的区别:
长路运算会将逻辑运算符两侧的运算先执行完成后再进行逻辑运算 ,而短路运算先执行逻辑运算符左侧的部分,如果符合要求则直接输出逻辑运算结果,而不再对右侧的进行运算。
注意:
- 长路与运算&,在两边都是整数时,是逐位与运算;在两边是关系运算时,是逻辑运算。
- 长路或运算|,在两边都是整数时,是逐位或运算;在两边是关系运算时,是逻辑运算。
三种逻辑运算的优先级为:非运算>与运算>或运算
安全起见,使用小括号将先要运算的关系式括起来。
括号与运算符级别,不做过多赘述,没意义!想要先运算的,添加括号即可,没人神经病去记那些运算符优先级。
枚举类型的使用:
1
2
3
4
5
6
7
8
9public class FirstSample {
public static void main(String[] args) {
Size s = Size.SMALL;
}
enum Size {SMALL,MEDIUM,LARGE,EXTER_LARGE};
}
3.6 字符串
实例化String对象
- 直接赋值(更为常用)
- 使用关键字new
String内容的比较
1
2
3
4
5
6
7
8
9
10
11String str = "hello";
String str1 = new String("hello");
System.out.println(str.equals(str1));//输出的结果为true
//“==”比较的是地址
//“equals”比较的是内容
//字符串的遍历
for(int i=0;i<str.length();i++){
char ch = str.charAt(i);
System.out.println(ch);
}字符串内容是不可更改的,改变的是堆内存地址的指向。
String字符串常用方法
- 字符串长度:
length()
- 字符串转换数组:
toCharArray()
- 从字符串中取出指定位置的字符:
charAt()
- 字符串与Byte数组的转换:
getBytes()
- 过滤字符串中存在的字符:
indexOf()
- 去掉字符串的前后空格:
trim()
- 从字符串中取出子字符串:
subString()
- 大小写的转换:
toLowerCase()
toUpperCase()
- 判断字符串的开头结尾字符:
endWith()
startWith()
- 替换String字符串中的一个字符:
replace()
- 字符串长度:
StringBuffer:
- 缓冲区,本身也是操作字符串,但与String不同,StringBuffer是可以更改的。
- 操作类,必须通过实例化进行操作。
1
2
3StringBuffer sb = new StringBuffer();//实例化
sb.append("Java笔记");//添加内容
System.out.println(sb.toString());StringBuffer常用方法
append()
添加字符串insert(位置int,字符串String)
插入字符串replace(开始替换位置int,结束替换位置int,字符串String)
替换字符串indexOf()
过滤字符串中存在的字符
StringBuffer:
一个可变的字符序列,StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候,速度更快。但若涉及线程安全方面,建议使用StringBuffer。
常用方法:
append()
insert()
3.7 输入输出
标准输出流。
System.out.println();
标准输入流。
1
2Scanner in = new Scanner(System.in);
String name = in.nextLine();int nextInt();
double nextDouble();
格式化输出
System.out.printf("%s,%8.3f\n","string",1111.22222);
保留数字小数点后16位,并转换成字符串输出。1
2
3
4
5
6
7
%s,输出字符串。
%8.3f,输出浮点数,总长度为8,小数点保留3位,右对齐。如果为”%-8.3f“,则表示左对齐。
- ```java
System.out.println(String.format("%.16f", sum));System.out.printf("%tc",new Date());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
格式化当前日期及时间,并打印。具体的格式,见《Java核心技术-卷Ⅰ》的p59。
4. 文件的输入与输出
- 文件读取
> 1. Scanner in = new Scanner(Paths.get("文件路径"),"文件编码方式");
> 2. Scanner in = new Scanner(new File("文件路径"));
> 3. Scanner in = new Scanner(new BufferedReader(new FileReader("文件路径")));
读取文件并在控制台输出:
```java
//如果文件路径包含反斜杠,则需要在每个反斜杠之前加一个额外的反斜杠
Scanner in = new Scanner(new File("文件路径"));
while(in.hasNext()){
System.out.println(in.next());
}文件写入
PrintWriter out = new PrintWriter(“文件路径”,”文件编码方式”);
//会覆盖掉已有内容
out.println(“我爱Java”);
追加内容写入文件:
1
2
3
4
5
6
7
8
9
10File f = new File("文件路径");
FileWriter fw = new FileWriter(f, true);
PrintWriter pw = new PrintWriter(fw);
pw.println("我爱Java");
pw.println("Java爱我");
pw.flush();
fw.flush();
pw.close();
fw.close();
System.out.println("写入成功!");
3.8 控制流程
块(即复合语句)是指由一对大括号括起来的若干条简单的Java语句。块确定了变量的作用域(一般来说,变量出了大括号就失去了作用)。一个块可以嵌套在另一个块中。不能在嵌套的两个块中声明同名的变量。
条件语句
if语句
1
2
3if(条件表达式){
条件表达式结果为true时,执行本代码块
}if else 语句
1
2
3
4
5if(条件表达式){
条件表达式结果为true时,执行本代码块
}else{
条件表达式结果为false时,执行本代码块
}if嵌套语句
1
2
3
4
5
6
7
8
9if(条件表达式1){
条件表达式1结果为true时,执行本代码块
}else if(……){
……
}else if(条件表达式n){
条件表达式n结果为true时,执行本代码块
}else{
条件表达式n结果为false时,执行本代码块
}循环结构语句
while 循环
当满足条件时进入循环,执行循环体;当条件不满足时,跳出循环。
1
2
3
4while(循环继续的条件表达式){
条件表达式为true时,执行本代码块。继续循环。
条件表达式为false时,退出while循环。
}do while 循环
1
2
3do{
循环内容;
}while(循环继续的条件表达式);for 循环
1
2
3for(循环变量初始化;循环继续的条件表达式;循环变量值变更){
循环内容
}switch语句
1
2
3
4
5
6
7
8
9
10
11
12switch(表达式){
// case与字面量值之间要有空格
case 常量值1:
代码块1;
break;
case 常量值2:
代码块2;
break;
……
default:
以上常量值均不是时,执行本代码块。
}switch语句的“贯穿”现象:当一个case结束后没有
break;
语句,则会一直向下执行,直至退出switch语句块。中断控制语句:
goto语句不被Java所使用,goto也仅作为保留字。
break;
语句用于跳出当前循环或语句块。带标签的break语句。
1
2
3
4
5
6
7
8int n = 5;
break_out: //break标签
for(;;){ //无限循环
if(n>0) {
break break_out;
}
}
System.out.println("我是带标签的break语句!");注意:标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。
continue;
语句,用于跳过当前循环,进入下一次循环。
3.9 大数值
java.math包中的两个类:BigInteger和BigDecimal,可以处理包含任意长度数字序列的数值。
1
2
3
4
5
6
7
8
9
10int x = 6;
// 使用静态的valueOf方法可以将普通数值转换位大数值
BigInteger a = BigInteger.valueOf(x);
// 也可以先存储为字符串再进行转换
BigInteger b = new BigInteger("111111111111");
// 计算a*b
BigInteger result = a.multiply(b);
System.out.println(a+"*"+b+"="+result);在进行算术运算时,需要用到大数值类中的add、multiply等方法。
3.10 数组
数组,是有序的元素序列。数组中的每个元素具有相同的数组名,下标是其元素的唯一标识。
数组的下标是从0开始的。
声明及开辟数组空间
数组的声明
- 声明形式一:
type arrayName[];
- 声明形式二:
type[] arrayName;
- 声明形式一:
为数组分配内存空间,如果不分配内存,将不能访问它的任何元素。
我们使用new关键字来为数组分配内存空间。
eg:
1
2int[] score=null;//数组的声明
score = new int[3];//为数组开辟内存空间,也称为实例化
数组初始化方式有2种:
动态初始化
1
2
3int[] score=null;//数组的声明
score = new int[3];//为数组开辟内存空间,也称为实例化
//也可直接写成 int[] score = new int[3];静态初始化
1
int[] score={1,2,3};
匿名数组
1
2
3
4int[] small = {98,36};
// 此处的 new int[] {1,2,3,4,88,77}即为匿名数组
small = new int[] {1,2,3,4,88,77};匿名数组可以在不创建新变量的情况下重新初始化一个数组。
数组遍历
方法一:for循环
1
2
3
4
5int[] a = { 45, 4, 89, 48, 78787 };
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}方法二:for each循环
1
2
3for(int element:a) {
System.out.println(element);
}方法三:Arrays.toString
1
2
3int[] a = { 45, 4, 89, 48, 78787 };
System.out.println(Arrays.toString(a));
// 结果为[45, 4, 89, 48, 78787]数组拷贝
如果需要将一个数组的所有值拷贝到一个新的数组中去,需要用到Arrays类中的copyOf方法:
1
Arrays.copyOf(original, newLength)
第二个参数是新数组的长度,通常用该方法增加数组的大小。
如果数组元素是数值型,那么多余的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数组元素。
数组排序
优化过的数组排序方法Arrays.sort():
1
2int[] a = {1,45,2};
Arrays.sort(a);多维数组
二维数组的声明与分配内存
1
2type arrayName[][];
arrayName[][] = new type[行][列];二维数组的遍历:
1)两层for循环
2)两层for each循环
3)Arrays.deepToString(a);
注意:
- 数组中的null与空是两个完全不同的概念
- 数组长度可以为0
- 数组声明后未赋值前,int类型数据默认为0,布尔类型数据默认为false,对象类型默认为null。