JAVA基础阶段技术总结
Java基础知识
概述
Java是1995年SUN公司发布,如今被Oracle收购。
Java是一门半编译半解释的面向对象语言。
Java由于虚拟机JVM的存在,所以可以跨平台运行。
Java程序运行过程
public class Test{
//主方法,是程序的入口,有且只有一个
public static void main(String[] args){
System.out.println("Hello World!");
}
}
编辑的是.java文件,称为源文件。通过javac命令进行编译,生成同名的.class字节码文件,在虚拟机上解释该字节码文件运行。
数据类型
原始类型
整型 :byte (1字节) short(2字节) int(4字节) long(8字节)
浮点型: float(4字节) double(8字节)
字符型 : char(2字节)
布尔型 boolean(true/flase)
引用类型
- 数组
- 类
- 接口
类型转换
自动类型转换
-
小字节类型数据可以直接保存到大字节类型的变量中。
-
整型数据可以直接保存到浮点型变量中。
short s=123;
int i=s;
long num=123;
float f=num;
强制类型转换
同类型下,如果大字节类型的数据强制保存到小字节类型的变量中,需要强制类型转换
int i=123;
byte b=(int) i;
变量
保存数据的内存区域,其中的数据可以变化。
定义变量
数据类型 变量名;
变量赋值
变量名=值;
=右边的值有默认的数据类型。
整数默认为int,小数默认double类型。
变量初始化
数据类型 变量名 = 值;
变量需要定义、赋值后才能使用。
int i=0;
System.out.println(i);
运算符
算术运算符
需要两个操作数参与,如果有浮点数参与运算,结果为浮点型。
符号 | 作用 | 说明 |
---|---|---|
+ | 加 | 如果两个操作数都是数值型的数据,+用于计算。如果两个操作数有一端是字符串,+用于拼接字符串。 |
- | 减 | 只能用于数值型数据。 |
* | 乘 | 只能用于数值型数据。 |
/ | 除 | 只能用于数值型数据。如果两个整数相除,结果只保留整数部分(商)。 |
% | 取余 | 只能用于数值型数据。商一定是整数。 |
注意
-
如果同时多个符号一起使用,遵循数学中的四则运算规则,先乘除,后加减
-
运算时最终结果的数据类型,以所有参与运算的操作数中所占字节最大的类型为准
System.out.println(8/3+3*5%2.0);//2+15%2.0 => 2+1.0 => 3.0
关系运算符
需要两个操作数参与 ,计算结果为布尔型boolean(true/false)
符号 | 作用 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于 |
== | 等于 |
注意
- ==用于判断相等,=用于赋值
- ==用于比较两个原始类型的值或引用类型的内存地址
- 关系运算的结果为true/false
逻辑运算符
符号 | 作用 | 说明 |
---|---|---|
&& | and与 | 符号两端需要两个表达式,判断如果都为true,整体结果则为true,如果有一端结果为false,整体结果为false。 |
|| | or或 | 符号两端需要两个表达式,判断如果都为false,整体结果则为false,如果有一端结果为true,整体结果为true。 |
! | not非 | 是一个单目运算符,只有一个表达式参与运算。"!表达式"表示对原表达式的结果取相反值。 |
注意
- &&和||符号两端是两个表达式
- &&和||称为短路运算符,当第一个表达式能确定结果时,不再判断第二个表达式
赋值、复合赋值运算符
符号 | 作用 |
---|---|
= | 赋值运算符。将符号右侧的内容赋值给符号左侧的变量。 |
+= | 复合赋值运算符。a+=3相当于a=a+3; |
-= | 复合赋值运算符。 |
*= | 复合赋值运算符。a*=b+c相当于a=a*(b+c) |
/= | 复合赋值运算符。 |
%= | 复合赋值运算符。 |
注意
复合赋值运算的流程是:
将符号两端的整体进行对应的算术运算后,将结果赋值给符号左侧的变量中。
int a=3;
a*=a+2;//相当于a=a*(a+2)//3*5,最终a的值为15
自增、自减运算符
只有一个操作数参与运算,称为单目运算符
符号 | 作用 |
---|---|
++ | 将结果+1 |
– | 将结果-1 |
注意
-
a++或++a相当于a+=1或a=a+1。–同理
-
如果++或–独立成行使用,无论符号在前在后,都将结果+1或-1
int num=10; // num++; ++num; System.out.println(num);//11
-
如果++或–不是单独成行
- 符号在前,先+1或-1计算后再使用值
- 符号在后,先使用值后再+1或-1计算
int a=3; if(a++>3){//符号在后,先使用,即3>3不成立 } System.out.println(a);//a最终会+1,4 int b=4; if(--b==3){//符号在前,先计算,即3==3成立 } System.out.println(b);//3
条件运算符
三目运算符,有三个操作数参与。是一个简化版的双分支条件语句。
表达式1?表达式2:表达式3
首先运算表达式1,如果结果为true,执行问号后的表达式2;
如果结果为false,执行冒号后的表达式3。
运算符的优先级
小括号>>单目运算符(!、++、–)>>算术>>关系>>逻辑>>条件>>赋值
int year=2000;
String res=(year%4==0&&year%100!=0)||year%400==0?"闰年":"平年";
一个表达式中,如果有不同的数据类型参与运算,最终的结果以表达式中字节最大的数据类型为准。
int a=12;
double b=3;
double res=a/b;
double res=10.0/4;
double res=10/4.0;
double res=(double)10/4;
条件语句
if语句
小括号中都是一个表达式,最终结果为布尔型
- 单分支if语句
如果一件事情满足则执行,不满足什么都执行。
if(判断条件){//判断条件的结果为布尔值
条件满足时执行的代码
}
- 双分支if语句
如果一件事情有两种情况,满足执行某些内容,不满足则执行另一些内容
if(判断条件){
条件满足时执行的代码
}else{
条件不满足时执行的代码
}
- 多分支
依次判断条件是否成立,如果有一个分支成立,后续分支不再判断
if(判断条件1){
如果判断条件1满足时执行
}else if(判断条件2){
如果判断条件2满足时执行
}else if(判断条件3){
如果判断条件3满足时执行
}else{
如果所有条件都不满足时执行
}
-
嵌套
if嵌套不要嵌套太多层,会导致代码可读性变低。if嵌套可以改造成if(){return}形式,让程序满足条件时,不再执行后续内容
if(){
if(){
}
}else{
if(){
}
}
注意
-
在方法的if语句中出现return,就不再执行后续的代码。
-
如果方法的返回值是void,return后无需添加值,如果不是void,return后必须添加值。
-
if或else后的大括号可以不写,但只能让后边紧邻的第一句话成为满足时执行的语句。
public static void main(String [] args){
if(2>1){
return;//提前结束main方法
}
System.out.println("程序结束");//这句话不会输出
}
public int chu(int a,int b){
if(b==0){
System.out.println("0不能作为除数");
return 0;
}
return a/b;
}
int num=10;
if(num==10)
System.out.println("xxxx");//这句话是if满足时执行的内容
else
System.out.println("yyyy");//这句话是if不满足时执行的内容
int a = 10;
if (a < 0)
a++;//这行属于if的满足时执行的内容,此时条件不成立,不执行
a++;//这行不属于if的内容,是一句独立的代码,要执行
System.out.println(a);//11
switch语句
开关语句
如果一个变量的值能够例举出时,使用switch语句更为简洁。
switch(变量){//要判断的变量,只能是非long整型、字符型char和字符串String和枚举类型
case 值:
//如果变量的值与当前case的值匹配,执行这里的代码
break;
case 值:
//如果变量的值与当前case的值匹配,执行这里的代码
break;
...
default:
//如果没有任何值与变量的值匹配,执行这里的代码
break;
}
注意
- swtich小括号中的变量只能是非long的整型、字符型char、字符串String和枚举类型
- 小括号中的变量类型要与case后的值的类型相匹配
- 如果有某个case后的内容和变量值匹配,执行case后的代码,如果没有任何case匹配,执行default后的代码
- break和default可以省略。如果不写break,在某个case匹配时,执行玩相应的代码后继续执行后续case后的代码,直到遇到break或没有代码为止
- 如果多个case后执行的内容一致,可以省略break,将统一要做的代码放在最后的case后
可以不写break,会继续执行后续case后的内容。
如果能例举出一件事情的分支,建议使用swtich语句。
如果一件事情的分支是范围时,只能使用if语句。
循环语句
如果要重复执行某些代码时,使用循环语句。
while
while(循环条件){//小括号中的条件结果为boolean值
满足循环条件时重复执行的代码
}
执行流程
先执行小括号中的内容,如果结果为true,执行大括号中的内容,再循环执行小括号中的内容,判断如果为false则停止循环。
while循环有可能一次都不执行。
do-while
do{
满足循环条件时重复执行的代码
}while(循环条件);
执行流程
先执行一次do大括号中的内容,再判断while小括号中的内容,如果成立,再次执行do大括号中的内容,如果不成立,停止循环。
do-while循环至少执行一次
for
for(定义循环变量;循环条件;更新循环变量){
循环体
}
执行流程
首先执行表达式1,再执行表达式2,如果表达式2的结果为true,执行循环体,再执行表达式3,再执行表达式2判断,如果表达式2的结果为false,结束循环。
注意
-
while和for循环如果条件一开始就不成立,一次都不执行。do-while循环会至少执行一次后再做判断。
-
循环条件都是布尔值。
-
当已知循环次数时,建议使用for循环;未知循环次数时,建议使用while循环;先执行一次后再判断时使用do-while循环。
循环控制
break和return
所有的循环都可以使用break和return停止循环。
break是停止循环后,继续执行循环之外的内容。
return是结束方法,不再执行return之后的内容。
public static void main(String[] args) {
int i = 1;
while (true) {//死循环
System.out.println("xxxxx");
if (i++ == 10) {
break;//退出整个循环,程序继续执行循环之外的内容
// return;//退出整个方法,程序不再执行之后的代码
}
}
System.out.println("结束");//如果循环中有return,不会执行这句话
}
continue
在循环语句中,使用continue,可以停止本次循环,不再执行continue之后的代码,直接进行下一次循环。
int i = 1;
while (i < 10) {
if (i++ % 2 == 0) {
continue;//如果遇到continue,结束本次循环(不再执行continue之后的代码),直接进入下一次循环
}
System.out.println(i);
}
//最终打印2 4 6 8 10
注意
- break终止整个循环
- 如果循环中有swtich语句,switch中的break只能终止switch,不能终止循环。
- continue停止本次循环,进行下次循环。(不再执行continue后续的代码)
- break和continue通常配置if语句使用
循环嵌套
循环嵌套就是循环一个循环。
//用*打印矩形
//将循环一行这件事再循环5次
for (int n = 1; n <= 5; n++) {
//循环打印一行
for (int i = 1; i <= 10; i++) {
System.out.print("*");
}
System.out.println();
}
在循环中继续循环。外层循环执行一次,内层循环执行一轮。
注意
- 循环嵌套不要嵌套太多层。
数组
概念
一组类型相同的数据的有序集合。
关于数组
实际在内存中是一块连续的空间。是保存数据的区域。
数组定义时需要确定大小和数据类型,不可改变。
定义数组时的变量保存的是实际内存空间的地址。
数据中保存的数据称为元素,每个元素有一个唯一的位置,称为索引(下标),这个索引从0计数。
可以通过数组的索引给数组赋值或读取数组中某个索引上的值。
数组的定义
语法:数据类型[] 数组名; 或 数据类型 数组名[];。建议使用前者。
定义数组后,如果不初始化数组,数组无法使用。
数组的初始化
语法:数组名=new 数据类型[数组大小];
- 数据类型[] 数组名 = new 数据类型[]{元素1,元素2…};
- 数据类型[] 数组名 = {元素1,元素2…};
数组的赋值
动态赋值
通过**数组名[索引]**给数组中某个位置赋值
int[] list = new int[10];
list[0]=123;//索引从0开始
list[9]=22;//最大索引为数组大小-1
list[22]=5;//能通过编译,但是在运行时会抛出数组越界异常
静态赋值
在定义数组的同时赋值
-
数据类型 [] 数组名 = new 数据类型[]{元素1,元素2,…}
String[] nameList = new String[]{"小明","王海","刘希"};
-
数据类型 [] 数组名 = {元素1,元素2,…}
String[] nameList = {"小明","王海","刘希"};
注意
-
数组一旦初始化后,数组大小不能改变,其中的元素类型要统一
-
数组的索引范围是[0,数组大小-1],使用时不能超出范围。在编译时无法识别是否超出数组索引,但运行时会抛出"数组索引溢出"异常
-
数组一旦初始化后,如果没有赋值,默认有初始值
数组数据类型 默认值 整型 0 浮点型 0.0 引用类型(如String等) null 布尔型 false 字符型 空白字符
读取数组中的元素
通过**“数组名[索引]”**读取某个索引对应的元素
String[] nameList={"王海","刘涛","赵敏"};
System.out.println(nameList[0]);
System.out.println(nameList[1]);
System.out.println(nameList[2]);
增强for循环
专门用于遍历数组或集合元素的一种循环
语法:for(数据类型 变量名 : 数组名){}
String[] list = {"admin","qwe","aaa"};
//使用增强for循环遍历
for(String name : list){
System.out.println(name);
}
数组特点
-
数组可以通过“数组名.length”获取其长度
-
数组定义后,如果没有对其赋值,会有默认值
- 整型默认0,浮点型默认0.0,字符默认空白字符,布尔型默认false,引用类型默认null
-
通常使用增强for循环遍历数组
方法总结
IDEA快捷键
- 一键调整代码格式:ctrl + alt + L
- 快捷生成main方法:psvm或main
- 快捷生成输出一句:sout或“xxx”.sout
- 快速生成if语句:条件.if
- 输出包含遍历对象的foreach快捷键:遍历对象.for
- Ctrl + D:复制行
- Ctrl + /:添加行注释
- Ctrl + Shift + /:添加块注释
穷举法
将所有可能的情况一一例举出来。
//鸡兔同笼 笼子里有若干鸡和兔,头一共35,腿一共94,鸡兔各几只?
for (int ji = 0; ji <= 35; ji++) {
for (int tu = 0; tu <= 35; tu++) {
if (ji + tu == 35 && 2 * ji + 4 * tu == 94) {
System.out.println("鸡:" + ji + "兔:" + tu);
}
}
}
//百元买百蛋 花够100元买够100个蛋 鸡蛋3个1元 鸭蛋1个3元 鹅蛋1个5元
for (int jd = 0; jd <= 100; jd++) {
for (int yd = 0; yd <= 100; yd++) {
for (int ed = 0; ed <= 100; ed++) {
//整数间相除为整数,这里鸡蛋的价格需要用浮点数表示
if (jd + ed + yd == 100 && 3 * yd + 5 * ed + jd / 3.0 == 100) {
System.out.println("鸡蛋:" + jd + "鸭蛋:" + yd + "鹅蛋:" + ed);
}
}
}
}
冒泡排序
数组中每相邻的两个元素进行比较,如果不满足排序的规则,交换位置。
//冒泡排序
//每相邻的两个元素进行比较,如果不满足排序的要求,则交换位置
//如要将 9 7 5 2 1 这组数据进行升序排序
//第一轮比较:7 5 2 1 9 比较了4次 97 95 92 91
//第二轮比较:5 2 1 7 9 比较了3次 75 72 71
//第三轮比较:2 1 5 7 9 比较了2次 52 51
//第四轮比较:1 2 5 7 9 比较了1次 21
//比较轮数i 每轮比较次数j
//1 4
//2 3
//3 2
//4 1
//i=数组长度-1 j=数组长度-i
冒泡排序核心代码
//外层循环控制比较的轮数
for(int i=1;i<=数组.length-1;i++){
//内层循环控制每轮比较的次数
for(int j=1;j<=数组.length-i;j++){
//判断是否要交换位置
if(数组[j-1] < 数组[j]){//如果不满足降序的条件(小于)则交换位置
//借助第三个变量交换数组中元素的位置
int temp = 数组[j];
数组[j]=数组[j-1];
数组[j-1]=temp;
}
}
}
举例
public class ArrayTest5 {
public static void main(String[] args) {
//定义一个整型数组,将其中的元素进行升序排序
int[] list = {17, 22, 13, 20, 32};
//外层循环表示比较的轮数
for (int i = 1; i <= list.length - 1; i++) {
//内存循环表示每轮比较的次数
for (int j = 1; j <= list.length - i; j++) {
//每次比较时,判断是否满足排序要求,如果不满足则交换位置
if (list[j - 1] > list[j]) {//这里需要升序,所以如果第一个元素大于第二个元素,就要交换位置
//交换位置
int temp = list[j - 1];//先将其中任意一个索引上的元素取出来
list[j - 1] = list[j];//再将另一个元素放过去
list[j] = temp;//再将第一个元素放回来
}
}
}
//打印排序后的元素
for (int i : list) {
System.out.println(i);
}
}
}
生成随机数的方法
Random rd = new random();
//生成[0,num)范围内的随机int数
int res=rd.nextInt(int num);
数组工具类Arrays
Arrays是jdk提供的用于处理数组的工具类。包含了如排序、复制、填充等方法,这些方法都是静态方法,直接通过Arrays调用。
常用方法 | 作用 |
---|---|
sort(数组) | 将输入中的元素升序排序。 |
sort(数组,起始位置,结束位置) | 对数组中[起始位置,结束位置)区间的元素升序排序。 |
fill(数组,值) | 使用指定值对数组中的所有元素进行填充。 |
fill(数组,起始位置,结束位置,值) | 使用指定值对数组中[起始位置,结束位置)区间的元素进行填充。 |
copyOf(数组,新数组长度) | 复制数组并指定复制后的数组的长度。得到复制后的新数组。 |
asList(一组数据) | 将一组数据转换为List集合。 |
equals(数组1,数组2) | 判断两个数组是否相同,得到判断的布尔值。只有两个数组一模一样时得到true。 |