关于Java程序开发的认识与了解:
Java程序开发的步骤:
(1)编写代码
(2)启动cmd
(3)调用javac编译,生成 .class的字节码文件(c表示:compile编译)
(4)调用java运行
集成开发环境IDE(Integrated Development Environment):是一种专门用来提高Java开发效率的软件。
免费的IDE中,有Eclipse,收费的IDE中,有IDEA,而且全世界用的最多的就是IDE,IDE社区版是免费的。
JDK(Java Development Kit):
即java开发工具包=JRE+java的开发工具(java、javac、javadoc、javap等)
JRE(Java Runtime Environment):
java运行环境=JVM+java的核心类库(类)
JVM(Java Virtual Machine):java虚拟机
如果想要运行一个开发好的Java程序,只需安装JRE即可。
数据类型:
数据类型分为:基本数据类型和引用数据类型
java的8种基本数据类型
(1)byte:字节型,用来存储整数的,占用1个字节,范围是-128到127。
(2)short:短整型,用于存储整数的,占用2个字节,范围是-32768到32767。
(3)int:整型,用于存储整数的,占用4个字节,范围-2^31到2^31-1。
(4)long:长整型,用于存储整数的,占用8个字节,范围-2^63到2^63-1。
(5)float:单精度浮点数,用于存储小数的,占用4个字节,不能表示精确的值。
(6)double:双精度浮点数,用于存储小数的,占用8个字节,不能表示精确的值。
(7)boolean:布尔型,用于存储true或flase的,占用1个字节。
(8)char:字符型,采用Unicode字符编码格式,用于存储单个字符,占用2个字节
默认值:
1、整型直接量默认为int类型
2、浮点数直接量默认为double类型
3、byte、short、int类型默认值:0
long类型:0L
float类型:0.0F double类型:0.0D
int
1、整数直接量默认为int类型,但不能超出范围,若超范围则发生编译错误
2、两个整数相除,结果还是整数,小数部位无条件舍弃(不会四舍五入)
3、运算时若超范围,则发生溢出(溢出不是错误,但是需要避免)
Integer a = Integer.MAX_VALUE;//int的最大值:2147483647
System.out.println(a);
int b = a + 1;
System.out.println(b);//int的最小值:-2147483648,运算时发生溢出(溢出需要避免)
//int c = 2147483648;//超出范围,编译错误
long
1、长整型直接量需在数字后面加L或l
2、运算时若有可能溢出,建议在第一个数字后面加L
int a = 1234567890*987654321;
long b = 1234567890*987654321;
long c = 1234567890L*987654321;
System.out.println(a);
//-671530190:运算中发生溢出(需要避免)
System.out.println(b);
//-671530190:
//运算中先发生溢出(在编译期间算出结果并产生溢出),然后再将最终结果转换为long类型
System.out.println(c);//1219326311126352690
//在第一个数后面加L,默认是long类型的数值运算,没有发生溢出
double和float
1、浮点数直接量默认为double类型,若表示float需在数字后面加F或f
2、double和float类型在参与运算时,有可能发生舍入误差,精确场合不能使用
注:浮点数的精度是有限的,一般情况下只是一个近似值,永远不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。在财务系统中,一般会在Java中使用BigDecimal类来计算财务报表
实例: 隐藏陷阱:求出1-1/2+1/3-1/4...1/100的和
隐藏陷阱:
当一个int类型整数/另一个int类型的整数,其结果会舍掉小数部位,若再将结果赋值给double类型的变量时,此时会将一个整数int值赋给double变量,此处也就失去了使用double类型的意义
char字符:
1、采用Unicode字符集编码格式,一个字符对应一个码,表现形式是char,但其本质是int(0-65535之间)
2、字符型直接量必须放到单引号''中,有且仅有一个字符
需要记住的几个char字符ASCII码:
'a'----97;'A'-----65;'0'-------48
3、特殊符号需要转义符号\来实现
4、最小值是:'/u0000'(即为0) 最大值是:'/uffff'(即为65535)
类型间的转换:
byte----short----int----long----float----double
char----
两种转换方式:自动转换和强制转换
1、自动/隐式类型转换:小类型到大类型
2、强制转换:大类型到小类型-----(要转换成的数据类型)变量
强转有可能发生溢出或丢失精度
char类型与byte、short之间可以相互转换,但必须强转,超出类型范围则发生溢出
两点规则:1、整型直接量可以直接赋值给byte,short,char,但不能超出范围
2、byte,short,char型数据参与运算时,系统一律自动将其转换为int再计算
public class Test {
public static void main(String[] args) {
//整型直接量赋值(不能超出其类型范围,否则编译错误)
byte b = 127;
short s = 100;
char c = 165;
System.out.println(b);//127
System.out.println(s);//100
System.out.println(c);//¥
//自动转换(小到大)
int b1 = b;
int s1 = s;
int c1 = c;
System.out.println(b1);//127
System.out.println(s1);//100
System.out.println(c1);//165
//char类型的扩展
//char类型强转为byte、short
//short s2 = c;//编译错误,char类型不能自动转换为short
short s2 = (short)c;//将char类型强制转换为short类型
//byte b2 = (byte)c;编译错误,char类型不能自动转换为byte
byte b2 = (byte)c;
//将char类型强制转换为byte类型,因为byte范围:-128到127,165超出其范围,发生溢出
System.out.println(s2);//165
System.out.println(b2);//-91(发生溢出)
//byte、short类型强转为char
//char c2 = s;//编译错误,short类型不能自动转换为char
char c2 = (char)s;//将short类型强制转换为char类型
//char c3 = b;//编译错误,byte类型不能自动转换为char
char c3 = (char)b;//将byte类型强制转换为char类型
System.out.println(c2);//d
System.out.println(c3);//
}
}
变量:
方法里面的变量:使用之前必须先声明并初始化。
变量的作用域范围:
从变量的声明开始,到包含它最近的大括号结束
变量的同名问题:
作用域重叠,变量不能同名
补充:
命名法:
1、小驼峰命名法:第1个单词首字母小写,其余单词首字母大写-----方法名、变量名
2、大驼峰命名法/帕斯卡命名法:所有单词首字母大写--------类名
1b = 8bit
import引入
1、Scanner扫描仪:
import java.util.Scanner;//引入一个扫描仪
public class Test{
Scanner scan = new Scanner(System.in);//新建一个扫描仪scan
int a = scan.nextInt();//用户输入-----将扫描到的整数赋给int变量a
double b = scan.nextDouble();//用户输入-----将扫描到的double数据赋给double变量b
}
2、生成随机数:random(0.00000...到1之间的随机小数)不包含int整数1
int a = (int)(Math.random()*10+1);
System.out.println(a);//输出一个1到10的随机数,不需要import
import java.util.Random;
class Test {
Random rand = new Random();
int a = rand.nextInt(100);//随机生成一个[0,100)之间的整数,不包含100
}
3、println、print输出
println:“输出并换行”,print:“输出不换行”
System.out.println();/System.out.print();
运算符
1、算数运算符:+ ,- ,* ,/ ,++ ,--
++/--:自增1/自减1,可在变量前也可在变量后
1、单独使用时,在前在后都一样
2、被使用时,在前在后不一样
a++/a--:整体结果为a
++a/--a:整体结果为a+1/a-1
不管是a++或++a,在这个过程中,a始终自增1结果为a+1
2、关系(比较)运算符:> , < , >= , <= , == , !=
关系运算的结果为boolean型,关系成立则为true,关系不成立则为false
3、逻辑运算符:&& , || , !
1、&& :短路与(并且)两边真都为真,见false则false
当第1个条件位false时,发生短路,后面的也就不执行了
2、|| : 短路或(或者),有真则为真,见true则true
当第1个条件位true时,发生短路,后面的也就不执行了
3、!:逻辑非(取反),非真则假,非假则真
补充:&为不短路与,| 为不短路或,不管前面条件是否为真,后面的都会执行
4、赋值运算符:= ,+= ,-= ,*= ,/= ,%=
1、简单赋值运算符:=
2、扩展赋值运算符:+= ,-= ,*= ,/= ,%=
扩展赋值运算符自带强转功能
short s = 5;
s = s + 5;//编译错误,需强转:s = (short)(s + 5)
s += 5;//相当于s = (short)(s + 5)
5、字符串连接:+
1、若两边为数字,则做加法运算
2、若两边出现了字符串,则做字符串连接
3、任何类型与字符串相连,结果都会变为字符串类型----同化作用
System.out.println("java"+1+2+3+4+"JAVA");
//输出:java1234JAVA
System.out.println("java"+1+2+3+4);
//输出:java1234
System.out.println(1+2+3+4+"JAVA");
//输出:10JAVA
//上述3种结果最后都为字符串类型
6、条件/三目运算符 :boolean?语句1:语句2
Boolean为true,执行语句1;false执行语句2
switch可以用于什么类型的数据上
byte、short、int、char、String、枚举类型,其他类型不允许。
三种结构:
顺序结构、分支结构、循环结构
分支结构:
if(boolean){ if(boolean){ if(boolean){ switch(boolean){
} }else{ }else if(boolean){ case 1: 语句块1
} ... break;
}else{ case 2: 语句块2
} break;
...
default :
}
注:1、default可写在switch中的任何地方,可用可不用,当没有匹配的case时,执行default
2、break语句用来执行完一个case分支后使程序跳出switch语句块;如果没有写break,
程序会顺序执行到switch结尾,除非遇到break。
switch...case的运用实例
题目:接收用户输入的年份和月份,判断该年该月共有多少天
//闰年:能被4整除且被100整除;能被400整除
int y = 2;
int x = 0;
switch (y){
default:
case 0:
x -= 1;
break;
case 1:
x += 5;
}
System.out.println(x);
//default(默认值),可以写在switch里的任何地方,
//但无论写在哪儿,都一定是先匹配case,当所有case
//都未匹配时才执行default
//y=2,此时走default中的语句块,因为没有break
//所以程序往下执行,执行case 0时,有break跳出当前循环,输出x:-1
循环结构:
循环的三要素:(1)循环变量的初始化
(2)循环的条件(以循环变量为基础)
(3)循环变量的改变(向着循环的结束变)
while(boolean){ do{ for( 要素(1) ; boolean型(2) ; 要素(3) ){
循环体 循环体 循环体(4)
} }while(boolean); }
死循环实例: for执行过程:1234 243243...2432
while(true){ for( ; ; ){
循环体 循环体
} }
注:for中的循环变量num的作用域仅在当前for中,但不同作用域中的num是可以重叠的(不同的for循环中可以使用同一个变量i)
循环结构的选用:
1、是否跟次数有关---------true-------直接选用for
2、然后看第一元素与第三元素是否相同,相同-----直接选用do-----while
不相同---直接选while
嵌套循环:
1、循环中套循环,常常多行多列时使用,一般外层控制行,内层控制列
2、执行过程:外层循环走一次,内层循环走所有次
3、建议:嵌套层数越少越好
4、break只能跳出当前一层循环
关键字:break
break用于跳出循环,它只能跳出当前一层循环(不使用标签时)
break语句可以指定退出哪层(使用标签时label,指定到哪个label就退出到哪里),但在实际开发中,尽量不要使用标签(可读性会变差)
如果没有指定break,默认跳出最近的循环体
当跳出时,break后面/剩余的语句不会执行
关键字:continue
continue可以跳出循环体中剩余语句而进入到下一次循环
数组介绍
数组:可以存放多个同一类型的数据,它是相同数据类型元素的集合。数组也是一组数据类型,是引用类型,数组型数据是对象
数组的下标是从0开始的;
数组声明、初始化:
数组声明: double[] scores;//声明数组,这时scores是null
scores = new double[];//分配内存空间,可以存放数据
数组初始化:
静态方式: int[] a = {1,2,3,4,55,10};
事先已经知道数组a里面有6个元素,具体值也知道,用静态方式较方便。
动态方式: int[] b = new int[6];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
a[4] = 55;
a[5] = 10;
事先只知道6个元素,但后续才知道各个元素的值,需要之后赋值。
数组默认值
类型 | int | double | boolean | String | char |
默认值 | 0 | 0.0 | false | null | /u0000 |
数组的复制:
方法一: System.arraycopy(a,1,b,0,4);//灵活性好
// a:源数组 ;
//1:源数组的起始下标 ;
// b:目标数组 ;
// 0 :目标数组的起始下标 ;
// 4 :要复制的元素个数
public class Test {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b = {0,0,0,0,0,0};
System.arraycopy(a,0,b,1,5);
//从数组a的下标0开始复制,复制到数组b(下标1开始,共复制5个元素)
System.out.println(Arrays.toString(b));
}
}
//输出:[0, 1, 2, 3, 4, 5]
//最终结果是:把数组b从下标1开始位置的5个元素都替换掉了
方法二: int[] b = Arrays.copyOf(a,6);//灵活性差
将数组a复制给数组b
// a:源数组 ;
// b:目标数组 ;
// 6 :目标数组的长度(元素个数) ;
// 若目标数组长度 > 源数组长度,则末尾补默认值。
若目标数组长度 < 源数组长度,则将末尾截掉。
public class Test1 {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b1 = Arrays.copyOf(a,4);
int[] b2 = Arrays.copyOf(a,6);
System.out.println(Arrays.toString(b1));
System.out.println(Arrays.toString(b2));
}
}
/*
[1, 2, 3, 4]
[1, 2, 3, 4, 5, 0]
*/
注:方法二需要在main方法前引入:import java.util.Arrays;
数组扩容:
用数组复制(方法二)还有一种特殊用法,可以给数组扩容。
a = Array.copyOf(a,a.length+1);//相当于给数组a长度加1
扩容后最后一个元素是默认值
当然,也可以进行缩容。
数组的追加:
import java.util.Arrays;
//将数组b追加到数组a上
public class Test1 {
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int[] b = {6,6,6};
//先给数组a扩容,扩容后最后元素有默认值0
a = Arrays.copyOf(a,a.length+b.length);
System.out.println(Arrays.toString(a));
//再将数组b复制到扩容后的数组a中,将默认值替换为b中的元素
System.arraycopy(b,0,a,a.length-b.length,b.length);
//输出数组a
System.out.println(Arrays.toString(a));
}
}
/*
[1, 2, 3, 4, 5, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 6, 6]
*/
数组排序:
Array.sort(a);//对数组array升序排序
数组输出:
System.out.println(Arrays.toString(数组引用名))可以输出数组
冒泡排序:排序的核心就是“对比”与“换位”。
注:1、此次演示的是升序排序,若将if中的条件:< 改为 > ,输出的结果是降序排列
选择排序:
排序原理(升序):不同于冒泡排序,选择排序不是在每次对比之后都要交换位置,第一轮用1个元素与后面的每个元素对比,当小于第2个元素的值时,不用交换,直到遇到第n个元素大于第1个元素,然后与第n个元素进行交换,重复第一轮,直到最小的值交换到最后一个位置。第二轮仍然用第1个元素与后面的每个元素对比,但是每次交换的次数比第一轮减1(因为第一轮最小的值位置已固定),直到第n轮对比交换完,排序结束。
生成一个随机的int型数组:
import java.util.Random;//系统可自动添加
import java.util.Arrays;//系统可自动添加
//生成一个随机int数组
class randomArray{
public static void main(String[] args){
Random rand = new Random();
//当输入Ra时,系统会弹出Random,直接回车,可在类前添加import...
int arrayBound = 100;//定义一个随机数的上限(不包含100)
int arrayCount = 50;//定义一个数组的元素数量,也是数组的长度
int[] array = new int[arrayCount];
for(int i = 0;i <array.length;i++){
array[i] = rand.nextInt(arrayBound);
}
System.out.println(Arrays.toString(array));//回车系统弹出的Arrays
}
}
//输出结果:[49, 87, 21, 44, 97, 74, 64, 14,...,94, 9, 56, 72,]//随机数组
插入排序:
插入到某个元素前面(后面),插入后一轮结束。
补充:冒泡排序
向左读取:该排序可实现每一轮的循环都能将每一轮的最大值放到最终位置
向右读取:该排序可实现每一轮的循环都能将每一轮的最小值放到最终位置
二维数组:
二维数组本质:是将多个一维数组作为另一个一维数组的元素,在绝大部分应用场景中,二维数组的“第二维度”的数组长度是相同的。
但也可以不相同,比如:map[][]是一个二维数组,int map[][] = {{1,2},{3, 4, 5}},map[0]是一个含有两个元素的一维数组,我们也称为列数不等的二维数组。
列数相等时,二维数组可以看做是一个矩阵
7 | 1 | 9 | 6 |
4 | 2 | 8 | 1 |
6 | 0 | 3 | 5 |
二维数组的声明:
1、一维数组的声明方式有:int[] x或者int x[]
2、二维数组的声明方式有:int[][] y 或者int[] y[] 或者int y[][]
//声明:int[]x,y[];
//判断x,y是什么数组
// x:int[] x;x是int类型的一维数组
y:int[] y[];y是int类型的二维数组
二维数组静态初始化:
int[] [] array ={{7, 1, 9, 6},{4, 2, 8, 1},{6, 0, 3, 5}};
System.out.println(array[0][2]);//输出9
array[ 横排下标][竖排下标]
二维数组动态初始化:
int[] [] array = new int[3][4];//第一个[]里面必须写,第二个[]里面可以不写
意义:初始化了一个长度为3的一维数组,且元素都是数组,每个元素数组的长度都是4。
也可以用此种方法定义: int[] [] array = new int[3][];//有3个一维数组,array.length为 3, array数组元素均为null
array[0] = new int[4];//第1个一维数组有4个元素
array[1] = new int[4];//第2个一维数组有4个元素
array[2] = new int[4];//第3个一维数组有4个元素
二维数组的遍历:
int[] [] array = {{7, 1, 9, 6},{4, 2, 8, 1},{6, 0, 3, 5}};
for(int i = 0;i < array.length; i ++){
for(int j = 0;j < array[i].length; j ++){
System.out.println(array[i] [j]);
}
}
方法介绍
何为方法:封装了一段特定的业务逻辑功能。
方法与方法之间必须是并列关系,(main之外的)方法放main前后都行
方法名:采用“小驼峰”命名
方法的五要素:
修饰词 返回值类型 方法名(参数类型 参数名){
方法体(具体的业务逻辑功能实现)
}
修饰词:public static
返回值类型 ------------有返回值-----return 值;//值(变量名或表达式等),返回的是一个具体的值
------------无返回值---void
参数类型:8中基本类型+数组类型,参数名:采用“小驼峰”命名
方法的6种类型及调用:
方法调用:
无返回值:方法名(有参传参)
有返回值:数据类型 变量名 方法名(有参传参)
main方法调用其他方法,有参传参,无返回值则不用返值到main方法中。
return:
return用在方法中,表示跳出方法,如果使用在main,表示退出程序。
return的使用:
(1)return 值;//(1) 结束方法的执行 (2)返回结果给调用方
------------用在有返回值的方法中
(2)return; //(1)结束方法的执行 ---------用在无返回值的方法中
方法的重载:
1、发生在同一类中,方法名相同,参数列表不同
2、编译器在编译时会根据方法的签名自动绑定方法
方法的签名:方法名+参数列表(参数类型 参数名,...)
方法的签名与有无返回值、参数名无关,只与方法名、参数列表多少有关。
对象:
数据类型 引用类型变量 指向 对象
Student zs = new Student();//创建了一个学生对象