java核心技术卷I
JAVA核心技术卷1
3. java的基本程序设计结构
3.1 基础
1.用命令行运行java
win+r cmd打开命令行
第一句:转到路径 第二句:编译,生成对应的class文件 第三句:运行
cd C:\Users\Administrator\IdeaProjects\untitled\src
C:\Users\Administrator\IdeaProjects\untitled\src>javac ClassName.java
C:\Users\Administrator\IdeaProjects\untitled\src>java ClassName.java
java api在线文档Overview (Java Platform SE 8 ) (oracle.com)
2.注意事项
java区分大小写
骆驼命名法:每一个单词的开头大写
public class ClassName {//源代码的文件名得与公共类的类名一样
public static void main(String[] args)
{
System.out.println("hello");//使用System.out调用了它的println方法
System.out.print("hello");//不在输出后加换行
}
}
注释:(其中两种和C++一样)
第三种注释:(可以自动生成文档)/** */
/**
*
*
*/
复制上一行代码是ctrl+d
3.2 数据类型
- 整型:(P29)
int short long byte
长整型数值有一个后缀L或者l,声明 float 型常量,须后加‘f’或‘F',double后面不一定要加d,因为默认就是双精度的,十六进制前面有一个前缀0x/0X,八进制有一个前缀0,前缀0b/0B为二进制
可以为数字字面量加下划线,比如1_000_000,只是为了更加方便阅读,编译器会去除这些下划线
- 浮点类型
float double
public class ClassName {
public static void main(String[] args)
{
double x = 10;
x = Double.NaN;//NaN表示出错,不是一个具体的数
if(Double.isNaN(x))//判断一个数是不是NaN
System.out.println("对味了");
else System.out.println("离谱");
}
}
- Unicode和char类型
字符可以用\u0000~\uFFFF
- boolean类型
false true
注:JAVA中不能用数值代替布尔值
if(x=0)//编译会报错,x=0不能转换为布尔值
3.3变量和常量
- 声明和变量起名和C艹差不多
初始化变量
未初始化的变量的值不能直接使用。
int vacationDays;
System.out.println(vacationDays);//error
-------------------------------------------
int vacationDays=12;//也可以这样
-------------------------------------------
var vacationDays=12;//变成int
var greeting="hello";
- 常量
可以用final指示常量
public class ClassName {
public static final double CM_PER_INCH = 2.54;//写在外面可以在一个类的多个方法中使用,称为类常量
public static void main(String[] args)
{
// final double CM_PER_INCH = 2.54;
double paperWidth = 8.5;
double paperHeight = 11;
System.out.println("size:" + paperWidth * CM_PER_INCH + " by " + paperHeight * CM_PER_INCH);
}
}
- 枚举类型
enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE};
- 运算符
double x = 4;
double y = Math.sqrt(x);//计算平方根
System.out.println(y);
y = Math.pow(x,2);//计算幂
System.out.println(y);
补充:Math方法里面的常量
Math.PI
Math.E
import static java.lang.Math.*;//加了这个 后面的不用加"Math"
public class ClassName {
public static void main(String[] args)
{
double x = 4;
double y = sqrt(x);
System.out.println(y);
y = pow(x,2);
System.out.println(y);
}
}
5.类型转换
一个二元运算符连接两个值的时候,先要将两个操作数转换为同一类型,然后再进行计算。
强制类型转换:
double x = 9.997;
int nx = (int)Math.round(x);
//round方法是四舍五入,会返回long类型,因此还是需要强制类型转换
6.赋值和自增自减和关系运算和条件运算类似C艹
7.switch
int seasonCode=3;
String seasonName = switch (seasonCode) {
case 0 -> "spring";
case 1 -> "summer";
case 2 -> "fall";
case 3 -> "winter";
default -> "???";//可以省略
};
System.out.println(seasonName);
int num = switch (seasonName) {
case "spring","summer","winter" ->6;//可以对应多个,
case "fall" ->4;
default -> -1;
};
System.out.println(num);
8.位运算类似C艹,运算符优先级(P43)
3.4字符串
String em = "";//空串
String greeting = "hello";
- 操作
//子串
String s = greeting.substring(0,3);//截取0~2位置上的字符,括号里第二个表示你不想取的第一个数
System.out.println(s);//输出hel
//拼接
String message = greeting + s;
System.out.println(message);//输出hellohel
//也可以拼接非字符串,会被自动变成字符串
int age = 15;
message = greeting + age;
System.out.println(message);
- 字符串不可变
java没有提供方法修改字符串中的某个字符,如果想修改:
String greeting = "hello";
greeting = greeting.substring(0,3)+"p!";//改为help!
System.out.println(greeting);
- 检测字符串是否相等
String s = "hello";
String t = "help!";
if(s.equals(t))//如果相等 返回true
System.out.println("yes");
else System.out.println("no");
"hello".equals(t)//也可以这样比较
"hello".equalsIgnoreCase("HELLO")//比较字符串不区分大小写(返回true
4.空串和null串
这俩是不一样的,null串是string专门存的一个为null的值
//判空
if(str.length() == 0)
if(str.equals(""))
//检查null
if(str == null)
if(str != null && str.length() != 0)
5.码点与代码单元
一些辅助字符需要一对代码单元表示
length方法返回代码单元个数
String str = "🍔hello";
int x = str.length();//代码单元个数
int y = str.codePointCount(0,str.length());//实际长度,即码点个数
System.out.println(x+" "+y);//输出结果7 6
//返回位置n的代码单元
char first = str.charAt(0);//h
6.String类的常用方法(p49)
7.构建字符串
char ch = 'h';
StringBuilder builder = new StringBuilder();//构建一个空的字符串构建器
builder.append("wlq");
builder.append(ch);//可以加入单个字符
String completedStr = builder.toString();//转换成String对象
System.out.println(completedStr);
StringBuilder类的重要方法(P54)
8.文本块
(注意文本块的缩进P55)
文本块以"""开头和结尾示例:
String greeting = """
hello
world
""";
System.out.println(greeting);
行尾的\会把这一行与下一行连接起来
String greeting = """
hello,my name is wlq.\
please enter your name:""";
//相当于"hello,my name is wlq.please enter your name:"
3.5输入输出
1.读取输入
//使用的类不是java.lang包里的 都需要导入包
import java.util.Scanner;//Scanner类
//构建一个与“标准输入流”System.in关联的Scanner对象
Scanner in = new Scanner(System.in);
System.out.print("what is your name?\n");
String name = in.nextLine();//可以有空格
System.out.println(name);
name = in.next();//不可以有空格,空格作为分隔符
System.out.println(name);
int age = in.nextInt();//读入int
Scanner类的常用方法:
int nextInt()
double nextDouble()//输入double
boolean hasNext()//检查输入中是否还有其他单词
boolean hasNextDouble()
boolean hasNextInt()//检查下一个字符序列是否表示一个整数或者浮点数
其它读入方式:BufferedReader
import java.io.*;
public class MyJavaApplication
{
public static void main(String[] args)
{
String s="";
System.out.print("please enter a string:");
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
s = in.readLine( );
} catch(IOException e){ }
System.out.println("You've entered string:"+s);
}
}
2.格式化输出
double x = 3.33;
int y = 10;
System.out.printf("这里有一个小数叫%f,有一个整数叫%d",x,y);//这个方法沿用C++
System.out.print(y);//只能这样打
3.6控制流程
块(block):一对大括号括起来
1.条件
if-else类似C++
2.循环
while和do-while类似C++
for也类似C++
switch见上面,C++版本得switch可以用。主要区分是有无->,case以冒号结束,有直通行为,否则没有。
3.break和continue
java提供了一种带标签的break语句,允许跳出多重嵌套的循环。
可以打一个标签,标签必须放在你想跳出的最外层循环之前,并且必须紧跟一个冒号。
public static void main(String[] args)
{
int T=5;
read_data://说明跳出的最外层循环,不是跳到这个位置
while(T-1>0)
{
T--;
for(int i=1;i<6;i++)
{
if(i>3)break read_data;
}
}
System.out.println(T);//输出结果是4
}
带标号的continue
public void findPimeByContinue(){
First_Loop:
for (int i = 2; i < 100; i++){
for (int j = 2; j < i; j++){
if (i % j == 0)
continue First_Loop;
}
System.out.println(i);
}
}
3.7大数
java.math包里有两个很有用的类BigInteger(用于整数)和BigDecimal(用于浮点数)
//需要导入包
import java.math.BigInteger;
BigInteger a = BigInteger.valueOf(100);
BigInteger reallyBig = new BigInteger("12131231242141242123132412343526346367457567564");
System.out.println(a+"\n"+reallyBig);//可以把两个大数打印出来
用大数进行运算时,不能用常规的+ *运算符,要用add和multiply方法
BigInteger a = BigInteger.valueOf(100);
BigInteger b = BigInteger.valueOf(200);
BigInteger c = a.add(b);//c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));//d = c * (b + 2)
api:java.math.BigInteger
BigInteger subtract(BigInteger other)//减
BigInteger divide(BigInteger other)//除
BigInteger mod(BigInteger other)//取余
BigInteger sqrt()//对这个大数开平方
int compareTo(BigInteger other)//判断大小,相等返回0,小了返回负数,大了返回正数
static BigInteger value0f(long)
api:java.math.BigDecimal(P79)
3.8数组
数据是引用类型
1.初始化:
int[]为类型名,a是变量名,也有人这么写in a[];但是最好类型和变量分开
int[] a;//声明整型数组a
a = new int[100];//初始化为一个可以存储100个整数的数组
//或者写在一起
int[] a = new int[100];
int a[5];//错误,不能这样声明
一旦创建了数组,就不能再改变它的长度。
也可以用变量定义:
int n = in.nextInt();//输入想开多大数组
int[] num = new int[n];
还可以不用写new,自动统计个数
int[] smallPrimes = {2, 3, 5, 7, 11, 13 };
String[] authors =
{
"sb",
"sd",
"wlq",
"lrl",
};
smallPrimes = new int[] {17,19,23,29,31};//重新初始化了
int n = smallPrimes.length;
for(int i = 0; i < n; i++ ) System.out.println(smallPrimes[i]);//输出的是后面的数
还可以直接赋值:
int[] smallPrimes = new int[1];//这个开多大的都无所谓
int[] anonymous = {13,19,23,29,31};
smallPrimes = anonymous;//已经变成anonymous的形状了
int n = smallPrimes.length;
for(int i = 0; i < n; i++) System.out.println(smallPrimes[i]);
2.访问数组元素
类似C++
创建数字数组时,初始化为0,bool数组会初始化为false,字符串数组会初始化为null,不是空串,要想要空串必须指定,比如说
for(int i = 0; i < name.length; i++) names[i] = "";
//array.length获取数组长度
- for each循环
java有一种循环结构可以遍历数组:
int[] anonymous = {17,19,23,29,31};
for (int element : anonymous)//元素和数组
System.out.println(element);
-
打印数组中的全部值
System.out.println(Arrays.toString(a));
-
数组拷贝
这里类似引用?把anonymous赋值给smallPrimes,但是修改smallPrimes的同时anonymous也被修改了
int[] anonymous = {17,19,23,29,31};
int[] smallPrimes = anonymous;
smallPrimes[3] = 12;
System.out.println(anonymous[3]);//输出12
如果只希望拷贝数值,用Arrays类里面的copy0f
int[] anonymous = {17,19,23,29,31};
int[] smallPrimes = Arrays.copyOf(anonymous, anonymous.length);
smallPrimes[3] = 12;
System.out.println(anonymous[3]);//还是29没有被改变
//也常用这种方法改变数组的长度
smallPrimes = Arrays.copyOf(smallPrimes, smallPrimes.length*2);//改变为原来的二倍
for(int element:smallPrimes)System.out.println(element);//后续的数都用0填充
- 命令行参数
用命令行运行java
javac ClassName.java
java ClassName -g cruel world
可以传入到args数组里,输出结果为:
-g
cruel
world
public class ClassName {
public static void main(String[] args) {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
}
}
- 数组排序
使用Array类里面的sort
int[] arr = {5,8,6,4,3,7,2};
Arrays.sort(arr);//变成有序的了
for(int element : arr)
System.out.println(element);
api:java.util.Arrays
3.9多维数组
初始化的方式:
int[][] a = new int[10][10];
int[][] b =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
遍历二维数组:
//方式一 用for each方式访问二维数组
for (int[] row : b)
{
for( int value : row)
System.out.print(value+" ");
System.out.println();
}
//方式二 以列表的形式打印二维数组
System.out.println(Arrays.deepToString(b));
//输出: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
java实际上是没有多维的数组,只有数组的数组
可以单独访问数组的某一行,交换数组
int[][] a =
{
{1,2,3},
{4,5,6},
{7,8,9}
};
int[] temp = a[0];
a[0] = a[1];
a[1] = temp;
System.out.println(Arrays.deepToString(a));//可以看出前两行已经交换
还可以利用这种方法创建一个不规则数组
final int N = 5;
int[][] a = new int[N][];
for(int i = 0; i < N; i++)
{
a[i] = new int[i+1];
}
System.out.println(Arrays.deepToString(a));
输出结果是:
[[0], [0, 0], [0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0]]
3.10 数值运算
逻辑运算类似C++
非简洁:
&”和“|” 做运算时,运算符左右两边的表达式总会被运算,然后对两表达式的结果进行与、或运算
简洁:
“&&”和“||” ,运算符右边的表达式有可能不被执行
位运算和三目运算也类似C++
对象运算符:
判断对象是否属于某指定类或其子类的实例,如果是则返回true,否则返回false。
boolean b = s instanceof String;
关系运算符的优先级高于逻辑运算符
4. 对象和类
面向对象程序设计:oop
4.1 基础
类常见的关系有:
- 依赖(uses-a)(一个类的方法要使用或操作另一个类的对象)
- 聚合(has-a)(类A的对象包含类B的对象)
- 继承(is-a)(爷知道)
依赖是最常见的,应该减少依赖(就是减少耦合)
依赖,会用到这个类:
class Car {
// Car 类的实现
}
class Driver {
public void driveCar(Car car) {
car.drive();
}
}
聚合,对象当对象:
class Student {
// Student 类的实现
}
class University {
private List<Student> students;
public University() {
this.students = new ArrayList<>();
}
public void addStudent(Student student) {
students.add(student);
}
}
4.2 使用预定义类
要想构造一个Date对象,需要在构造器前面加上new操作符
Date rightnow = new Date();//表达式new Date()构造了Date类型的对象,它的值是新创建对象的一个引用,再把这个引用存储在rigthnow对象变量中
System.out.println(rightnow);
对象变量:
Date startTime;//只是创建了一个对象变量,但不是对象
startTime = rightnow;//两个名字都指向同一个对象
startTime = null;
LocalDate类:
不要使用构造器来构造LocalDate类的对象,应当使用静态工厂方法。
LocalDate.now();
LocalDate.of(1999,12,31);
int year = newYearEve.getYear();
LocalDate later1000 = newYearEve.plusDays(1000);//newYearEve不会被改变
4.3 自定义类
1.用var声明局部变量:
var只能用于方法中的局部变量,参数和字段的类型必须声明
var harry = new Employee("",50000,199,20,1);
2.使用null引用
LocalDate rightNow = null;
String s = rightNow.toString();//NullPointerException异aaaaaa
对应null的两种解决方法:
//如果n是null,name是unknown
String name = Objects.requireNonNullElse(n,"known");
//如果n是null,抛出异常,msg为error
String name = Objects.requireNonNull(n,"error");
3.隐式函数与显式函数
在一个类的方法里,显示参数是方法括号里面的,隐式参数是对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!