javaSE(面向对象前篇)笔记录
这是我自己在观看B站的狂神说JAVASE面向对象前的所有篇章所做的一些笔记,大家有需要的可以看看,有错误的还请评论区纠正提醒一下我哈!
数据类型
在java中,定义Long类型要在数字后面加个L,不然会报错
定义float类型要在数字后面加个F,不然也会报错。
八大类型中不包括String,因为String不是关键字而是一个类
八大基本类型:byte , short , int , long , float , double , char , boolean
引用数据类型:类 , 接口 , 数组
位:是计算机内部数据储存的最小单位,11001100是一个八位二进制数
字节:是计算机中数据处理的基本单位,习惯上用大写B来表示
1B(byte , 字节) = 8bit(位)
字符:是指计算机中使用的字母、数字、字、符号
1bit表示1位
1Byte表示一个字节 1B = 8b。
1024B = 1KB
1024KB = 1M
1024M = 1G
在Java中,float能表现的字长是有限的,一般会存在舍入误差,
所以在float或double用于比较时会存在接近但不等于的情况,
故最好完全避免使用浮点数进行比较
float a = 46546546416545431654F;
float n = a + 1;
System.out.print(a == n);
输出结果:true
float a = 31654F;
float n = a + 1;
System.out.print(a == n);
输出结果:false
那么银行业务怎么表示?可以用BigDecimal类(数字工具类)来表示
所有的字符本质还是数字,故在java中可以进行数据类型强转
转义字符
\t 制表符(简单说就是添加8个空格间隔)
\n 换行符
eg:System.out.print(“Hello\tWorld”);
类型转换:
低 -------------------------------------------> 高
byte , short ,char -->int–>long–>float–>double
运算中,不同类型的数据先转化为同一类型,然后再进行运算!
强制转换: (类型)变量名 高–>低
自动转换: 低–>高
注意点:
- 不能对布尔值进行转换
- 不能把对象类型转换成不相干的类型
- 在把高容量类型转换到低容量的时候,需要强制转换
- 转换的时候可能存在内存溢出,或者精度问题!(强制转换和自动转换均存在)
public class example01 {
public static void main(String[] args) {//在intellij IDEA开发者工具中 Java中main方法快捷方式 psvm + 回车
//操作比较大的数的时候,注意溢出问题
int money = 10_0000_0000;//JDk7以后新特性,数字之间可以用下划线分割
int year = 20;
int total = money * year;//-1474836480 , 计算的时候溢出了
long total2 = money * year;//-1474836480 ,money * year计算结果默认是int类型,然后计算完之后再转换成long已经晚了,转换之前就已经存在了问题!
long total3 = money * ((long)year);//20000000000 , 先把一个数转换为long类型
System.out.println(total3);//在intellij IDEA开发者工具中 输出方法快捷键 sout + 回车
}
}
变量、常量、作用域
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
变量作用域:
- 类变量:跟实例变量一样定义在方法外,但要加上static关键字。在类中调用就无需通过对象名(或者类名.对象名)来调用,可以直接变量名调用。(定义方法时也可以加上static关键字,则在类中调用时直接通过方法名(或者类名.方法名)调用无需创建对象)
类变量是从属于类的,而且会随着该类一起出现一起消失!
2.实例变量:定义在类里面,方法外面,从属于对象。使用时要创建类的一个对象,
然后对象名.变量名调用实例变量。
<注意点:如果不自行初始化,整型变量默认值为0,浮点型默认值为0.0,布尔类型默认值为false
除了基本类型,其余的默认值都是null>
3.局部变量:定义在方法中,作用域也只能在定义的方法中间有效果,必须声明和定义初始化值。
常量:初始化后不能再改变值,不会变动的值。
所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
定义:
final 常量名 = 值;
```java
final double PI = 3.14;
```
<常量名一般使用大写字符!>
<在定义变量时,在变量类型前面的都是修饰符,如static、final、public等等,且修饰符不存在先后顺序,
eg: static final double PI = 3.14; 和 final static double PI = 3.14;俩种书写方式都是一样的效果!>
变量的命名规范:
1.所有变量、方法、类名:见名知意
2.类成员变量:首字母小写和驼峰原则:eg :monthSalary 除了第一个单词以外,后面的单词首字母大写。
3.局部变量:首字母小写和驼峰原则
4.常量:大写字母和下划线:MAX_VALUE。
5.类名:首字母大写和驼峰原则:Man,GoodMan。
6.方法名:首字母小写和驼峰原则:run() , runRun()。
基本运算符
<快捷键:Ctrl + D : 复制当前行到下一行>
<在做基本运算时,如果有Long类型或者Double类型的运算单元则结果就是Long类型的或者Double类型的
如果没有的例如short类型和byte类型的整型做运算其结果为int类型
同理,浮点数运算中没有存在Double类型的运算单元则运算结果就是float类型>
关系运算符的结果只有:true 和 false
自增自减运算符、初识Math类:
int a = 3;
int b = a++;//加号在后面,既先把a赋值给b,a再自增+1-----b为3
int c = ++a;//加号在前面,既a先自增+1,再把a赋值给c------c为5
幂运算:
在java中幂运算可以借用Math数学工具类
eg:
double pow = Math.pow(3,2);//后者2为次方数
System.out.println(pow);//输出结果为9
逻辑运算符、位运算符:
短路运算:
&&运算中,a&&b若前者为假后者b就不会被程序执行
int c = 5;
boolean d = (c<4)&&(c++<4);
System.out.println(d);//输出d为false
System.out.println(c);//输出c为5,既后者的(c++<4)没有被执行
||运算同理
位运算符:
//位运算----作为了解
public class example02 {
/*
* A = 0011 1100
* B = 0000 1101
*
* A&B = 0000 1100 二进制数A,B逐位比较,同一位都为1则为1否则为0
* A|B =0011 1101 二进制数A,B逐位比较,同一位都为0则为0否则为1
* A^B =0011 0001 (异或运算)二进制数A,B逐位比较,同一位相同则为0否则为1
* ~B =1111 0010 二进制数B简单逐为取反
*
* << *2 既二进制数往左移
* >> /2 既二进制数往左移
>> *箭头指向哪就往哪移动
* *效率极高!!!
* 0000 0011 3
* 0001 1000 24
* */
public static void main(String[] args) {
System.out.println(3<<3);
}
}
字符串连接符("+") :
eg:
int a = 10;//快捷键:Ctrl + D : 复制当前行到下一行
int b = 20;
//字符串连接符 +
System.out.println(a+b+"");//当""(虽然没有任何东西但它是String类型的)添加在a+b后面则a+b依旧进行运算,得30
System.out.println(""+a+b);//在a+b左侧加上了"",虽然没有任何东西但它是String类型的,然后就会把a+b操作数转化成String类型然后拼接起来,得1020
System.out.println(a+b+""+a);//同上结合理解,既前者a+b照常运算得30而后者a转化成String拼接上去,最终得3010
三目运算符:
x ? y : z ---- 既 x == true ,则结果为y,否则结果为z
Scanner用法
基本语法:
Scanner s = new Scanner(System.in);
<System.out输出,这边System.in输入,简记!>
Scanner类的next()和nextLine()方法获取输入的字符串,其区别为:
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("请输入兴趣爱好:");
String str1 = s.next();
/* next()注意点:
1.对输入有效字符之前的空格,next()方法会自动将其去掉
2.对输入有效字符之后的空格,next()方法会将其空格当成结束符,既next()方法不能得到带有空格的字符串*/
System.out.println("兴趣爱好是:"+str1);
Scanner s1 = new Scanner(System.in);
System.out.println("请输入兴趣爱好:");
String str2 = s1.nextLine();
/*
* nextLine()注意点:
* 1.以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符
* 2.nextLine()方法可以获得空格
* 故一般推荐使用nextLine()方法获取输入的字符串!
* */
System.out.println("兴趣爱好是:"+str2);
//凡是属于IO流的类,如果不关闭会一直占用资源,要养成好习惯用完就关掉!
s.close();
s1.close();
}
Scanner进阶使用:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//从键盘接受数据
int i = 0;
float f = 0.0F;
System.out.println("请输入整数: ");
if(sc.hasNextInt()){//hasNextInt()判断输入流中下一个输入是否是整数,是则返回True
i = sc.nextInt();
System.out.println("整数数据: "+ i );
}else{
System.out.println("输入的不是整数数据!");
}
System.out.println("请输入小数: ");
Scanner sc1 = new Scanner(System.in);
if(sc1.hasNextFloat()){//hasNextFloat()是判断输入流中下一个输入是否是浮点型数据,是则返回True
f = sc1.nextFloat();
System.out.println("浮点型数据: "+ f );
}else{
System.out.println("输入的不是浮点型数据!");
}
sc.close();
}
顺序结构
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
顺序结构是最简单的算法结构。
语句与语句之间,框与框之间是按从上到下的顺序执行,它是由若干个依次执行的处理步骤组成的,
它是任何一个算法都离不开的一种基本算法结构!!!
for循环:
在IDE里,100.for + 回车 会快捷生成简单的for循环
既生成: for(int i = 0 ; i<100 ; i++){
}
方法
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合,我们设计方法的时候,最好保持方法的原子性,
就是一个方法只完成1个功能,这样利于我们后期的扩展。
注意点:如果定义方法时返回类型不是void的话,在方法里就要有return返回值,一般把return放在方法的最底部(定义方法时不一定就只有一个return语句,特殊时候会使用return终止方法!!!),
<前提是该方法的返回类型不是void!!!>return除了能返回结果还有终止方法的意思,既就是程序一旦在方法里面碰到return,该方法就结束了!!!
在IDE中想看一些方法的源码:选中方法 ctrl + 单击 即可查看方法源码!!!
Java只有值传递没有引用传递!!!
方法的重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数
方法的重载的规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回类型可以相同也可以不相同
- 仅仅返回类型不同不足以成为方法的重载
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
命令行传承
有时候你希望运行一个程序时候再传递给它消息,这要靠传递命令行参数给main()函数实现
public static void main(String args[]){
for(int i = 0; i < args.length; i++){
System.out.println("args[" + i + "]" + args[i]);
}
}
Java中存在一种命令行传参,实践中不常用到,作为了解!!!
可变参数
之前虽未有涉及 , 但其实质就是数组 ,故着重理解并应用!
/*
* 可变参数!!!!-------》 其实质就是数组!!!
* JDK1.5开始,Java支持传递同类型的可变参数给一个方法 ------ 从而有效避免过多的方法重载
* 在方法声明中,在指定参数类型后加一个省略号(...)
* 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明!!!
*
* */
public static void main(String[] args) {
//调用可变参数的方法
Printmax();
Printmax(3,5,6,8,45,999,1111);
Printmax(new double[]{1,2,4,565,5454});
//以上三种方式都可以实现,其实可变参数的实质就是数组!!!
Update("相加", 1 , 2.0,3.0,4.0,5.0);
}
public static void Printmax(double... numbers){
if (numbers.length == 0){
System.out.println("没有传入参数!!!");
return ;//Printmax()方法定义的返回类型是void,故在此处碰到return不会终止方法!
}
double result = numbers[0];
//循环比较大小
for(int i = 1; i < numbers.length ; i++){
if (numbers[i] > result){
result = numbers[i];
}
}
System.out.println("最大值为: " + result);
}
public static void Update(String x ,int m , Double... y){
Double update = 0.0;
if (!x.equals("相加") && !x.equals("相减")){
System.out.println("无法判断做什么操作:!!!");
}
if (x.equals("相加")){
for (int i = 0; i < y.length; i++){
update = update + y[i];
}
update = update + m;
System.out.println("相加结果为: " + update);
}else if(x.equals("相减")){
for (int i = 0; i < y.length; i++){
update = update + y[i];
}
update = m - update;
System.out.println("相减结果为: " + update);
}
}
静态块
static{ } ------- 将类中只想加载一次的代码放在静态块中!也就是static的大括号中!
public :
java中public是一个访问权限修饰符,表示被修饰者有公共访问权限。
在java中一个类只能有一个public class 但可以有多个class!!!
内存分析:
java内存:堆 、 栈 、 方法区(这里只是简单了解一下)
堆:存放new的对象和数组 , 可以被所有的线程共享 , 不会存放别的对象引用
栈:存放基本变量类型(会包含这个基本类型的具体数值)
引用对象的变量(会存放这个引用在堆里面的具体地址)
方法区:可以被所有的线程共享,包含了所有的class和static变量
<声明的时候数组并不存在,只有创建的时候数组才存在!!!>
eg:
- 声明数组 int[] array = null; ----- 声明数组时,在栈中就会压入一个array,只是一个名字,空的里面没有东西!
- 创建数组 array = new int[10]; ------- 此时在堆中开辟了一片内存,这个空间就是array的名字,存放着10个int对象,
然后在给数组元素赋值的时候,将数组元素的值赋值给对应的int对象(如果不赋值时,数组元素默认是0,如果是String数组,那么默认的是null)
数组
数组是相同类型数据的有序集合
数组声明创建
首先必须声明数组变量,才能在程序中使用数组
dataType[] arrayRefVar; //首选的方法
或
dataType arrayRefVar[]; //效果相同,但不是首选方法
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
将声明与创建组合到一起:
int[] nums = new int[10];//其中10是定义数组的大小
数组的三种初始化
- 静态初始化:
int[] a = {1,2,3};
Man[] mans = {new Man(1,1) , new Man(2,2)};
- 动态初始化:包含默认初始化
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
- 数组的默认初始化:
数组是引用类型(除了基本八大类型以外的类型都是引用类型),它的元素相当于类的实例变量
因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化!
数组的四个基本特点:
-
其长度是确定的,数组一旦被创建,它的大小就是不可以改变的
-
其元素必须是相同类型,不允许出现混合类型
-
数组中的元素可以是任何数据类型,包括基本类型和引用类型
-
数组也是对象,数组元素相当于对象的成员变量。数组变量属引用类型,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
Arrays类
package Demo;
import java.util.Arrays;
//Arrays类包含用于操作数组的各种方法(如排序和搜索)。 该类还包含一个静态工厂,可以将数组视为列表。
/*Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意: 是"不用"而不是"不能"!!!)*/
public class ArraysDemo01 {
public static void main(String[] args) {
int[] a = {1,4,65,89,1654,1313,545,20};
//打印数组元素Arrays.toString
System.out.println(Arrays.toString(a));
Arrays.sort(a);//数组进行排序:升序
System.out.println(Arrays.toString(a));
Arrays.fill(a,0);//数组填充 将指定的字节值分配给指定字节数组的每个元素。
System.out.println(Arrays.toString(a));
Arrays.fill(a,3,5,6);
//将指定的字节值分配给 指定字节数组的指定范围 的每个元素。
// 待填写的范围从索引fromIndex (包括)扩展到索引toIndex ,排他。 (如果fromIndex==toIndex ,要填充的范围是空的。)
System.out.println(Arrays.toString(a));
// Arrays类中还有很多操作数组的方法,可以按住ctrl再点击类名Arrays进入Arrays类的源码,在点击IDE工具窗口的左侧Structure按钮查看类结构,寻找想知道的方法
}
}
冒泡排序
package Demo;
import java.util.Arrays;
/*
* 冒泡排序: 冒泡排序是一种简单的排序方式,掌握原理后可以进行升序排序也可以进行降序排序!!!
* 1.比较数组中,俩个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
* 2.每一次比较,都会产生一个最大,或者最小的数
* 3.下一轮则可以少一次排序
* 4.依次循环,直到结束!
* */
public class MaoPao {
public static void main(String[] args) {
int[] a = {1,54,98,654,384,66,579};
int[] result = sort(a);//调用完我们自己写的冒泡排序方法以后,返回了一个排序后的数组
System.out.println(Arrays.toString(result));
}
public static int[] sort(int[] array){
int temp = 0;//临时变量
//外层循环,判断我们这个要走多少次
for (int i = 0; i < array.length-1;i++){
boolean flag = false;//通过flag标识位减少没有意义的比较
//内层循环,比较判断俩个数,如果第一个数比第二个数大,则交换位置
for (int j = 0;j < array.length-1-i;j++){
if(array[j] > array[j+1]){
/*此时为升序排序,当想进行降序排序时,只需要将">"改为"<"即可,既相邻的俩个元素比较大小,将大的放置在前面,小的放置在后面*/
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if(flag == false){
break;
}
}
return array;
}
}
稀疏数组
package Demo.ShuZu;
import java.util.Arrays;
public class XiShuShuZu {
/*
* 当一个数组(包括多维数组)中的大部分元素为0或者为同一个数值的数组时,
* 为了节约空间起到压缩的效果,将数据用另一种结构来表示,即稀疏数组。
* */
public static void main(String[] args) {//本程序是狂神说java,JavaSE篇P59的案例程序代码
//1.创建一个二维数组 11 * 11 0:表示没有棋子 1:表示黑棋 2:表示白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始的数组
System.out.println("输出原始的数组: ");
//不能System.out.println(Arrays.toString(array1));这样输出。
// 对于二维或者多维数组来说使用Arrays.toString方法,只能输出一堆对象,故toString方法适合一维数组的输出
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
//转换为稀疏数组保存
//获取有效值的个数
int sum = 0;
for(int i = 0 ; i < array1.length ; i++){
for (int j = 0;j < array1[i].length ; j++){
if (array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数为: "+sum);
//2.创建一个稀疏数组
int[][] array2 = new int[sum+1][3];//稀疏数组的行数为原始数组有效值个数+1,列数规定为3
//第一行三个数组元素的值分别对应原始数组的行数、列数、有效值个数
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历原始二维数组,将非零的数组元素,存放在稀疏数组中
int count = 0;
for(int i = 0 ;i < array1.length;i++){
for(int j = 0;j < array1[i].length;j++){
if (array1[i][j]!=0){
count++;//在稀疏数组中,从第二行开始以下每一行对应一个原始数组中的有效值
array2[count][0] = i;//第一列存放有效值的行下标 ---- 指的是在原始二维数组中该有效值对应的行下标
array2[count][1] = j;//第二列存放有效值的列下标 ---- 指的是在原始二维数组中该有效值对应的列下标
array2[count][2] = array1[i][j];//第三列存放有效值的值
}
}
}
//输出稀疏数组
System.out.println("输出稀疏数组: ");
for (int i = 0;i < array2.length;i++){
for (int j = 0 ; j < array2[i].length;j++){
System.out.print(array2[i][j]+"\t");
}
System.out.println();
}
System.out.println("========================");
System.out.println("将稀疏数组还原!!!");
//1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];//这里是新建了一个二维数组来表示稀疏数组还原后的数组
//2.给稀疏数组其中的元素还原它的值
for (int i = 1 ; i < array2.length; i++){
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}//其他默认的为0,如果原始数组中大部分元素不是为0的话,可以先使用Arrays类中的fill方法将一个值分配给所有元素,再还原个别几个有效值的值
//打印
System.out.println("输出还原后的数组: ");
//增强型for循环,仅适合遍历输出数组元素
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}