个人主页:Hello Code. 本文专栏:Java基础知识 更多相关内容请点击前往Java基础知识总结【目录】查看 如有问题,欢迎指正,一起学习~~
前期准备
环境搭建
常用DOS命令
第一个Java程序
public class Hello{
public static void main(String[] args){
System.out.println("Hello World");
}
}
数据类型
常量
在程序的执行过程中,其值不会发生改变的量(数据)。
变量
就是内存中的存储空间,空间中存储着经常发生改变的值。
基本数据类型
引用数据类型
这部分后面会有专门的讲解,这里就不做过多说明了
键盘录入
目的
为了让数据更加灵活
步骤
- 导包:
import java.util.Scanner; (需要写在class上面) - 创建对象:
Scanner sc = new Scanner(System.in); (只有sc可以改变,其他属于固定格式) - 使用变量接收数据:
int i = sc.nextInt(); (只有i和sc变量可以改变,其他属于固定格式)
实例
import java.util.Scanner;
public class input{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int a = scan.nextInt();
System.out.println(a);
}
}
标识符
就是给类、方法、变量等起名字的符号
定义规则
- 由数字、字母、下划线(_)和美元符($)组成。
- 不能以数字开头
- 不能是关键字
- 严格区分大小写
常见命名约定
- 小驼峰命名法:常用于方法、变量
约定1:标识符是一个单词的时候,首字母小写 范例1:name 约定2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写 范例2:firstName - 大驼峰命名法:常用于类
约定1:标识符是一个单词的时候,首字母大写 范例1:Student 约定2:标识符由多个单词组成的时候,每个单词首字母都大写 范例2:GoodStudent
类型转换
隐式转换
将数据类型中,取值范围小的数据,给取值范围大的类型赋值,可以直接赋值
int a = 10;
double b = a;
简单记:小的给大的,可以直接给 4升的油,倒入8升的桶,可以直接倒入 小的数据和大的数据类型运算,小的会先提升为大的数据类型再进行运算 byte short char 这三种数据在运算的时候,无论是否有更高的数据类型,都会提升为int,然后再进行运算
强制转换
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量
- 格式:目标数据类型 变量名 = (目标数据类型)值或者变量;
int a = 10;
byte b = (byte)a;
int c = (int)88.88;
强制类型转换,有可能会发生精度损失
精度损失:简单理解,将容积为8升的水倒入容积为4升的桶中,多出的水会洒掉
案例
public class Test{
public static void main(String[] args){
byte a = 3;
byte b = 4;
byte c = a + b;
byte d = 3 + 4;
}
}
运算符
对常量或者变量进行操作的符号
表达式
用运算符把常量或者变量连接起来符合Java语法的式子就可以称为表达式。
不同运算符连接的表达式体现的是不同类型的表达式。
int a = 10;
int b = 20;
int c = a + b;
算术运算符
加(+)、减(-)、乘(*)、除(/)、取余(%)
加、减、乘都和小学一样,在用除法时,两整数相除只能得到整数,想要得到小数必须有浮点数参与运算 取余即指取结果的余数
字符之间相加时,字符会根据ASCII码值提升为int类型进行运算 (0–48 a–97 A–65)
int a = 1;
char b = 'a';
System.out.println(a + b);
字符串之间相加时,可以使用+和(任意数据类型)拼接 当‘+’操作中出现字符串时,这个‘+’是字符串连接符,而不是算术运算符 在‘+’操作中,如果出现了字符串,就是连接运算符,否则就是算术运算符,当连续进行‘+’操作时,从左到右逐个执行
System.out.println("java" + 666);
System.out.println(1 + 99 +"java");
System.out.println("5+5=" + 5 + 5);
System.out.println("5+5=" + (5 + 5));
自增自减运算符
自增(++)、自减(–)
- 单独使用时,++和–在前或者在后时结果都一样
- 当参与其他操作时,在前则先自增(自减)后进行操作;在后则表示先进行相应操作后进行自增(自减)
- 只能操作变量,不能操作常量
赋值运算符
赋值(=)、加后赋值(+=)、减后赋值(-=)、乘后赋值(*=)、除后赋值(/=)、取余后赋值(%=)
int a = 10;
a += 20;
System.out.println(a);
注意:扩展运算符底层会自带强制类型转换的功能
关系(比较)运算符
等于(==)、不等(!=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=)
注意:返回结果只有true或者false
逻辑运算符
- &(与):并且,全真则真,一假则假
- |(或):或者,全假则假,一真则真
- !(非):取反,真假假真
- ^(异或):两同为假,不同为真
- 短路逻辑运算符
- &&(短路与):作用和&相同,但有短路效果
- ||(短路与):作用和|相同,但有短路效果
逻辑短路:&&遇到false直接为false,不执行后面代码;||遇到true则直接为true,不执行后续代码
三元运算符
- 格式:
关系表达式 ? 表达式1 : 表达式2; - 执行流程
- 首先计算关系表达式的值
- 若为true则取表达式1的值
- 若为false则取表达式2的值
流程控制
通过一些语句,来控制程序的执行流程
顺序结构语句
程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序依次执行,程序中大多数代码都是这样的
分支结构语句
if语句
if(关系表达式){
语句体1;
}else{
语句体2;
}
- 执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true则执行语句体1
- 如果关系表达式为false就执行语句体2
- 继续执行后续代码
import java.util.Scanner;
public class A{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的年龄:");
int age = sc.nextInt();
if(age >= 18){
System.out.println("您已成年,可以进入");
}else{
System.out.println("对不起,您未成年,不能进入");
}
}
}
如果if语句中的语句体只有一条,那么大括号{}可以省略不写,但是不建议,容易混淆 if语句小括号后面不要写分号;
if(判断条件){
语句体1;
}else if(判断条件2){
语句体2;
}
...
else{
语句体n+1;
}
import java.util.Scanner;
public class A{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的成绩:");
int score = sc.nextInt();
if(score >= 90 && score <= 100){
System.out.println("优秀");
}else if(score >= 80 && score < 90){
System.out.println("良好");
}else if(score >=60 && score < 80){
System.out.println("及格");
}else if(score <60 && score >= 0){
System.out.println("不及格");
}else{
System.out.println("请输入正确的成绩!");
}
}
}
switch语句
switch(表达式){
case 值1:
语句体1;
break;
case 值2;
语句体2;
break;
....
default:
语句体n+1;
break;
}
- 格式说明:
- 表达式(将要被匹配的值)取值为byte、short、int、char、JDK5、以后还可以是枚举,JDK7以后可以是String
- case:后面跟的是要和表达式比较的值(被匹配的值)
- break:表示中断,结束的意思,用来结束switch语句
- default:表示所有的情况都不匹配的时候,就执行该处的内容,和if语句的else相似
- case穿透:
- 现象:当开始case穿透,后续的case就不会具有匹配的效果,内部的语句都会执行
直到看见break,或者将整体switch语句执行完毕,才会结束 - 应用场景:当多个case语句出现重复现象,就可以考虑使用case穿透来优化代码
循环结构语句
for循环
推荐明确循环次数时使用
for(初始化语句;条件判断语句;条件控制语句){
循环体语句;
}
- 执行流程
- 执行初始化语句
- 执行条件判断语句,看其结果是true还是false
如果是false,循环结束 如果是true,循环继续 - 执行循环体语句
- 执行条件控制语句
- 回到第2步继续循环
- 案例
for(int i = 1;i <= 5;i++){
System.out.println(i);
}
int sum = 0;
for(int i = 1;i <= 5;i++){
sum += i;
}
System.out.println(sum);
int sum = 0;
for(int i = 1;i <= 100;i++){
if(i % 2 == 0){
sum += i;
}
}
System.out.println(sum);
for(int i = 100;i <= 999;i++){
int sum;
int a = i % 10;
int b = i / 10 % 10;
int c = i / 100;
sum = a * a * a + b * b * b + c * c * c;
if(sum == i){
System.out.println(i);
}
}
System.out.print()为同行打印,不换行 System.out.println()自带换行效果,类似于html中的块级元素,独占一行。括号内无内容时可以当作换行符来使用
while循环
不明确循环次数时推荐while
while(条件判断语句){
循环体语句;
条件控制语句;
}
int i = 1;
while(int i <= 100){
System.out.println(i);
i++;
}
do…while循环
使用较少,了解即可
do{
循环体语句;
条件控制语句;
}while(条件判断语句);
- 三种循环的区别
- for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
- do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
- 条件控制语句中所控制的自增变量,因为归属于for循环的语法结构中,在for循环结束后,就不能再次被访问到了
- 条件控制语句所控制的自增变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用
死循环
for(;;){
循环体语句;
}
while(true){
循环体语句;
}
do{
循环体语句;
}while(true);
- 应用场景:
例如:键盘录入一个1-100之间的整数(用户可能出现误操作现象)
while(true){
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
if(a >= 1 && a <= 100){
}
}
continue与break关键字
- continue:跳过某次循环内容,继续开始下一层循环,只能在循环中使用
- break:跳出整个循环,终止循环体内容的执行,只能在循环和switch中使用
- 标号:可以给语句块加标号赋予它们名称,标号位于语句之前。标号只能被continue和break引用。
public class Test{
public static void main(String[] args){
int n = 1;
lo:
while(true){
switch(n){
case 1:
System.out.println("1");
break lo;
}
}
}
}
Random
作用
用于产生一个随机数
使用步骤
- 导包
import java.util.Random;
- 创建对象
Random r = new Random();
- 获取随机数
int number = r.nextInt(10);
int number = r.nextInt(10) + 1;
猜数字案例
import java.util.Random;
import java.util.Scanner;
public class a{
public static void main(String[] args){
Random r = new Random();
int ran = r.nextInt(100) + 1;
while(true){
System.out.print("请输入您猜的数字:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
if(n > ran){
System.out.println("猜大了~~");
}else if(n < ran){
System.out.println("猜小了~~");
}else {
System.out.println("猜恭喜你,猜对了,答案就是" + ran);
break;
}
}
}
}
开发神器-IDEA
概述
IDEA全称IntelliJ IDEA,是用于Java语言开发的集成环境,它是业界公认的目前用于Java程序开发最好的工具
集成环境
就是把代码编写、编译、执行、调试等多种功能综合到一起的开发工具
下载和安装
IDEA项目结构
project-module-package-class 这些结构的划分,是为了方便管理文件
- IDEA中的第一个代码
- 创建Project项目
- 创建Module模块
- 创建Package包
- 创建Class类
- 在类中编写代码
- 完成编译运行
注意:最后代码一定要存放到src目录下,包名类似于com.baidu.demo1这样的格式
常用快捷键
- psvm + 回车:快速生成main方法
- sout + 回车:快速生成输出语句
- alt + 1 :快速打开\隐藏工程目录结构
- alt + 4:打开\隐藏控制台
- Ctrl + alt + l:格式化代码
- alt + 回车:代码修正提示
- ctrl + D:向下复制一行
- ctrl + X:剪切当前行
- Ctrl + /:批量加入单行注释,再按一次就是取消注释
- Ctrl + shift + /:批量加入多行注释,再按一次就是取消
- ctrl + shift + ↑:上移当前行
- ctrl + shift + ↓:下移当前行
- Ctrl + alt + m : 将选中代码封装为一个方法
- 数组名.fori + 回车:快速遍历指定数组
- 集合.fori + 回车:快速遍历指定集合
数组
是一种容器,用来存储同种数据类型(或者比它所占字节小的)的多个值
格式
int[] array;
int array[];
初始化
Java中的数组必须先初始化,才能使用
所谓初始化,就是在内存中,为数组容器开辟空间,并将数据存入容器的过程
- 动态初始化:初始化时只指定数组长度,由系统为数组分配初始值(只明确元素个数,不明确具体数值,推荐使用)
- 格式:
数据类型[] 变量名 = new 数据类型[数组长度]; - 范例:
int[] arr = new int[3]; - 注意:打印数组变量名,输出的是数组在内存中的地址值
数组元素访问
- 数组内存地址的访问:
数组名 - 数组内部保存的数据的访问:
数组名[索引] - 索引从0开始,连续的,逐一增加
- 数组在创建完毕后,没有赋值也能取出,取出的值为0
- 默认值:
整数——0 浮点数——0.0 布尔——false 字符——空字符 引用数据类型——null
内存分配
Java程序在运行时,需要在内存中分配空间
为了提高效率,就对空间进行了不同区域的划分 每一片区域都有特定的处理数据的方式和内存管理方式
- 栈内存:方法运行时,进入的内存,局部变量都存放于这块内存当中
- 堆内存:new出来的内容就会进入堆内存,并且会存在地址值
- 方法区:字节码文件加载时进入的内存
- 本地方法栈:调用操作系统相关资源
- 寄存器:交给CPU去使用
静态初始化
初始化时,就可以指定数组要存储的元素,系统还会自动计算出该数组的长度(需求中明确了具体数据,直接静态初始化即可)
- 格式:
数据类型[] 变量名 = new 数据类型[]{数据1,数据2,数据3,....}; - 范例:
int[] arr = new int[]{1,2,3}; - 简化格式:
int[] arr = {1,2,3};
数组遍历
将数组中所有的元素取出来
动态获取数组元素个数:数组名.length
int arr = {1,2,3,4,5,6,7,8,9};
for(int i = 0; i <= arr.length; i++){
System.out.println(arr[i]);
}
注意:遍历是指取出数据的过程,不要局限的理解为:遍历就是打印
数据常见操作
- 获取最值
思路:定义一个变量,用于保存最大值(或最小值) 取数组中的第一个值作为变量的初始值(假设第一个值就是最大(小)值)与数组中的剩余数据逐个对比
int[] arr = {1, 2, 3, 4, 5, 6, 7000, 8, 919};
int max = arr[0];
for(int i = 0; i < arr.length; i++){
if(arr[i] > max) max = arr[i];
}
System.out.println("最大值为:" + max);
import java.util.Scanner;
public class test{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] arr = new int[];
int sum = 0;
for(int i = 0; i < arr.length; i++){
System.out.print("请输入第" + (i+1) + "个数值:");
int n = sc.nextInt();
sum += n;
}
System.out.println("数组内的元素的和为:" + sum);
}
}
int[] arr = {19, 28, 37, 46, 50};
Scanner sc = new Scanner(System.in);
System.out.print("请输入您要查找的数据:");
int n = sc.nextInt();
for(int i = 0; i < arr.length; i++){
if(arr[i] == n){
System.out.println("您要查找的数据索引为:" + i);
break;
}
}
方法
概念
方法就是一段具有独立功能 的代码块,不调用就不执行
使用前提
方法必须先创建才可以使用,该过程称为方法的定义 方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
方法定义
public static void 方法名(){
}
方法调用 方法名();
注意:方法必须先定义后调用,否则程序将会报错 方法与方法之间是平级关系,不能嵌套定义 在方法没有被调用的时候,都在方法区中的字节码文件(.class)中存储 方法被调用的时候,需要进入到栈内存中运行
带参方法的定义和调用
public static void 方法名(参数){
}
- 单个参数:
数据类型 变量名 - 多个参数:
数据类型 变量名1 , 数据类型 变量名2 , ..... - 调用:
方法名(参数); 方法名(变量名/常量值); 方法名(变量名1/常量值1 , 变量名2/常量值2 , ...);
方法调用时,参数的数量与类型必须与方法定义中的设置相匹配,否则程序将会报错
形参和实参
- 形参:全称形式参数,是指方法定义中的参数
- 实参:全称实际参数,是指方法调用中的参数
带参数方法练习
public class a{
public static void main(String[] args){
print(10, 20);
}
public static void print(int n, int m){
for(int i = n; i <= m; i++){
if(i % 2 != 0) System.out.println(i);
}
}
}
带返回值方法的定义和调用
public static 数据类型 方法名(参数){
return 数据;
}
方法定义时,return后面的返回值与方法定义上的数据类型要匹配,否则就会报错 在执行代码时,return语句后面的语句都不会执行,属于无效代码 return; 可以用于结束方法,也就是方法从栈内存中弹出去,该过程称为方法的弹栈
调用:数据类型 变量名 = 方法名(参数);
方法通用格式
public static 返回值类型 方法名(参数){
方法体;
return 数据;
}
方法重载
方法名相同,参数也完全相同,称为方法的重复定义,是一种冲突性的错误 在调用方法的时候,Java虚拟机会通过参数的不同来区分同名的方法
在同一个类中,定义了多个同名的方法,但每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系 注意:识别方法之间是否是重载关系,只看方法名和参数,和返回值无关
好处:不用记忆过多繁琐的方法名字
方法重载练习
public static void main(String[] args){
System.out.println(compare(20, 30));
}
public static boolean compare(byte a, byte b){
return a == b;
}
public static boolean compare(short a, short b){
return a == b;
}
public static boolean compare(int a, int b){
return a == b;
}
public static boolean compare(long a, long b){
return a == b;
}
方法的参数传递
- 当传入基本数据类型时,传入的是具体的数值,且方法中的变量和main中的变量并无联系
- 当传入引用类型时,传入的是具体的内存地址,这种情况可以在方法中改变引用类型变量的值
案例
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
printArray(arr);
}
public static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
if (i == arr.length - 1) System.out.print("]");
else {
System.out.print(", ");
}
}
}
public static void main(String[] args){
int[] arr = {11,33,44,88,22};
System.out.println("数组中的最大值为:" + max(arr));
}
public static int max(int[] arr){
int max = arr[0];
for(int i = 0; i < arr.length; i++){
if(arr[i] > max) max = arr[i];
}
return max;
}
public static void main(String[] args){
int[] arr = {11,22,33,44,2,2393,55};
int[] res = get(arr);
System.out.println("最大值为:" + res[0]);
System.out.println("最小值为:" + res[1]);
}
public static int[] get(int[] arr){
int max = arr[0];
int min = arr[0];
for(int i = 0; i < arr.length; i++){
if(arr[i] > max) max = arr[i];
if(arr[i] < min) min = arr[i];
}
int[] arrMaxAndMin = {max, min};
return arrMaxAndMin;
}
注意:return语句只能同时返回一个值,需要返回多个值的话可以使用数组
Debug
概述
是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序
操作流程
Debug调试,又称为断点调试,断点其实是一个标记,告诉Debug从标记的地方开始查看
添加断点 -> Debug运行 -> 根据Debug窗口调试(Step into向下进行;Stop停止) -> 删除断点
进制
指进位制:是人们规定的一种进位方式
常见进制
二进制、八进制、十进制、十六进制
计算机数据在底层运算的时候,都是以二进制进行的,了解不同的进制,便于我们对数据的运算过程理解的更加深刻
- 十进制:逢十进一,借一当十
- 二进制:逢二进一,借一当二(只有0和1)
- 八进制:逢八进一,借一当八(0,1,2,3,4,5,6,7)
- 十六进制:0~9,a~f(其中a~f表示10~15)
在Java中,数值默认都是十进制,不需要加任何修饰 二进制:数值前面以0b开头,b大小写都可 八进制:数值前面以0开头 十六进制:数值前面以0x开头,x大小写都可 注意:书写的时候,虽然加入了进制的标识,但打印在控制台展示的时候都是十进制数据
进制转换
- 任意进制到十进制公式:系数*基数的权次幂 相加
系数:每一【位】上的数 基数:几进制,就是几 权:从数值的右侧,以0开始,逐个+1增加 - 十进制到任意进制的转换公式:除基取余
使用源数据,不断地除以基数(几进制就是除几)得到余数,直到商为0,再将余数倒序拼起来即可 - 快速进制转换法:8421码
8421码又称BCD码,是BCD代码中最常用的一种 BCD:(Binary-Coded Decimal)二进制码十进制数 - 在这种编码方式中,每一位二进制值的1都是代表一个固定数值,把每一位的1代表的十进制数加起来得到的结果就是他所代表的十进制数
原码反码补码
注意:计算机中的数据,都是以二进制补码的形式在运算,而补码则是通过反码和原码推算出来的
-
原码:(可直观的看出数据大小)就是二进制定点表示法,最高位为符号位,0正1负,其余位表示数值的大小 一个字节等于8个比特位,也就是8个二进制位 -
反码:(将原码转换为补码)正数的反码与其原码相同,负数的反码是对其原码逐位取反,但符号位除外 -
补码:(数据以该状态进行运算)正数的补码与其原码相同,负数的补码是在其反码的末位加1
正数的原反补都是相同的 负数的【反码】,是根据【原码】取反(0变1,1变0)得到的==(符号位不变)== 负数的【补码】,是根据【反码】的末尾+1得到的
位运算
-
位运算指的是二进制位的运算,先将十进制数转换成二进制后再进行运算 -
在二进制位运算中,1表示true,0表示false & 位与:遇false则false,遇0则0 | 位或:遇true则true,遇1则1 ^ 位异或:相同为false,不同为true (a = a ^ b ^ b) ~ 取反:全部取反,0变1,1变0(也包括符号位) -
位移运算符: << 有符号左移运算,二进制位向左移动,左边符号位丢弃,右边补齐0 运算规律:向左移动几位,就是乘以2的几次幂 >> 有符号右移运算:二进制位向右移动,使用符号位进行补位 运算规律:向右移动几位,就是除以2的几次幂 >>> 无符号右移运算符,无论符号位是0还是1,都补0 -
案例:
public static void main(String[] args){
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a);
System.out.println(b);
}
int[] arr = {11, 22, 33, 44, 55, 66, 77};
for(int start = 0, end = arr.length - 1; start < end; start++, end--){
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
for(int i = 0 ; i < arr.length; i++){
System.out.println(arr[i]);
}
二维数组
二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器
定义格式
- 格式1:
数据类型[][] 变量名; - 格式2:
数据类型 变量名[]; - 格式3:
数据类型[] 变量名[];
动态初始化:数据类型[][] 变量名 = new 数据类型[m][n];
- m表示这个二维数组可以存放多少个一维数组==(行)==
- n表示每一个一维数组,可以存放多少个元素==(列)==
拓展:将一个提前创建好的一维数组存储到二维数组中
int[] arr = {11, 22, 33};
int[][] arr2 = new int[1][3];
arr2[0] = arr;
System.out.println(arr2[0][2]);
静态初始化:
- 格式:
数据类型[][] 变量名 = new 数据类型[][]{{元素1, 元素2,...}, {元素1, 元素2,...}...}; - 简化格式:
数据类型[][] 变量名 = {{元素1, 元素2,...}, {元素1, 元素2,...}, ...};
二维数组遍历
int[][] arr = {{11, 22, 33}, {33, 44, 55}};
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
System.out.println(arr[i][j]);
}
}
案例:
int sum = 0;
int[][] arr = {{22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}};
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
sum += arr[i][j];
}
}
System.out.println(sum);
|