1.java 数组理解
-
变量的类型不同,决定了变量在内存上占有的空间大小的不同。
-
数组是一组数据的集合
-
数组作为一种引用类型,申请的空间在堆中
-
数组元素的类型可以是基本类型,也可以是引用类型,但同一个数组只能是同一种类型
-
数组作为对象,数组中的元素作为对象的属性,除此之外数组还包括一个成员属性 length, length 表示数组的长度
-
数组的长度在数组对象创建后就确定了,就无法再修改了
-
数组长度不可变,那么数组怎么扩容呢?
-
原数组满了之后,可以新建一个新的容量更大的数组,将原数组中的数据拷贝到新数组中,原数组对象被 GC 回收,以后向新数组中存储数据。这就是数组的扩容。
-
-
数组元素是有下标的,下标从 0 开始,也就是第一个元素的下标为 0,依次类推最后一个元素的下标为n-1,我们可以通过数组的下标来访问数组的元素
- 小例子:求数组最大值
package cn.java.day01;
import java.util.Scanner;
//求数组最大值
public class T07 {
public static void main(String[] args) {
// 数组求最大值
int[] score = new int[5];
Scanner input = new Scanner(System.in);
// 赋值循环
for (int i = 0; i < score.length; i++) {
score[i] = input.nextInt();
}
// 默认第0项为最大值
int max = score[0];
for (int i = 1; i < score.length; i++) {
if (score[i] > max) {
max = score[i];
}
}
// max最大值
System.out.println(max);
}
}
2.数组排序
package cn.java.day01;
//导入工具类
import java.util.Arrays;
public class T08 {
public static void main(String[] args) {
// 数组排序
int[] nums = {2, 7, 99, 9, 77};
// 实现数组升序排序
Arrays.sort(nums);
}
}
- 数组的插入
package cn.java.day01;
import java.util.Scanner;
public class T09 {
public static void main(String[] args) {
// 数组插入元素
int[] nums = {2, 42, 61, 77, 79, 90, 100};
Scanner input = new Scanner(System.in);
// 定义变量来保存新插入的的分数
int score = input.nextInt();
// 找到插入元素的位置
int index = nums.length - 1;
for (int i = 0; i < nums.length; i++) {
if (score < nums[i]) {
index = i;
break;
}
}
// 元素后移
for (int j = nums.length - 1; j > index; j--) {
nums[j] = nums[j - 1];
}
// 重新赋值
nums[index] = score;
// 打印新的数组结果
for (int i = 0; i <nums.length ; i++) {
System.out.print(" "+nums[i]);
}
}
}
2.java引用类型和值类型
二维数组
与一维数组相同
Java中内存图:栈内存、堆内存、方法区。
- 栈内存:保存的是执行方法、运行方法(例如主方法)。
- 堆内存:保存的是具体的对象、数组等。
- 代码中带 new的就会在堆内存中开辟空间。
- 四类八种--基本数据类型
基本数据类型只有8种,可按照如下分类
①整数类型:long、int、short、byte
②浮点类型:float、double
③字符类型:char
④布尔类型:boolean
- 基本类型只是栈栈上存空间
- 引用类型
- 引用类型是堆和栈都要占空间。
引用数据类型非常多,大致包括:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
例如,String类型就是引用类型,还有Double,Byte,Long,Float,Char,Boolean,Short(注意这里和基本类型相比首字母是大写)
简单来说,所有的非基本数据类型都是引用数据类型
3.数据类型转换
Java中的数据转换主要分为两种:自动类型转换(也称为隐式转换)、强制类型转换(也称为显式转换)。
转换从低级到高级:byte、short、char(三者同级)——> int ——> long ——> float ——> double
- 自动类型转换:代码无需任何处理,在代码编译时 编译器会自动进行处理。特点——低级转换高级。
- 强制类型转换:需要在待转换数据类型前 使用 (type)value, type是要强制类型转换后的数据类型,可能会导致溢出或损失精度 。特点——高级转换低级。
数据类型转换必须满足如下规则:
- 不能对boolean类型进行类型转换。
- 不能把对象类型转换成不相关类的对象。
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
- 转换过程中可能导致溢出或损失精度,
- 例如: int i = 128; byte b = (byte)i; 因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,
- 例如: (int)23.7 == 23; (int)-45.89f == -45;
int 和 long 互转、int和double互转、int和byte互转、int和char互转、int和String互转
package cn.java.day01;
public class T02 {
public static void main(String[] args) {
int aInt = 20;
long bLong = 50L;
double cDouble = 4.8;
//低优先级类型数据 + 高优先级类型数据 ——> 结果会自动转换为高优先级数据
long sum = aInt + bLong;
//long -> int 需要强制类型转换
int d = (int) bLong;
//double -> int 需要强制类型转换
int e = (int) cDouble;
System.out.println("自动类型转换 int—>long: " + sum);
System.out.println("强制类型转换 long—>int: " + d);
System.out.println("强制类型转换 double—>int: " + e);
System.out.println();
//int 和 byte 转换
byte fByte = (byte) aInt; //高转低,强转
int gInt = fByte; //低转高,自动
System.out.println("高转低-强转,int->byte: " + fByte);
System.out.println("低转高-自动,byte->int: " + gInt);
System.out.println();
//int 和 char 转换
char hChar = 'a';
int iInt = hChar;
char j = (char) iInt;
System.out.println("低转高-自动,char->int: " + iInt);
System.out.println("高转低-强转,int->char: " + j);
System.out.println();
//int 和 String 转换
//int转String: 1)使用String的ValueOf方法 2)直接使用 String类+ (即字符串拼接),任意字符串和其他类型"+" 都会把其他类型转为字符串
String str1 = String.valueOf(aInt);
String str2 = "" + aInt;
System.out.println("int转String: " + str1 + ", " + str2);
//String转int:调用包装类的Integer.parseInt方法,当字符串中包含非数字时会出错
String str3 = "18";
int k = Integer.parseInt(str3);
System.out.println("String转int: " + k);
System.out.println();
//byte 和 char 互转
byte m = (byte) hChar;
char n = (char) m;
System.out.println("char->byte,强转: " + m);
System.out.println("byte->char,强转: " + n);
}
}
Java的八种基本类型:(按字节来分)
boolean 布尔型 1个字节 8bit(8位)
byte 字节类型 1个字节
char 字符类型 2个字节
short 短整型 2个字节
int 整型 4个字节
float 浮点型(单精度)4个字节
long 长整型 8个字节
double 双精度类型 8个字节
Java中默认的整数类型是int,如果要定义为long ,则要在数值后加上L或者l
默认的浮点型是双精度浮点,如果要定义float,则要在数值后面加上f或者F
一个字节等于8位,1个字节等于256个数。2^8
一个英文字母或者阿拉伯数字占一个字节
一个汉字占2个字节
4. 类和对象
类是具有相同属性和行为的一系列事物的集合。对象现实生活中看得见,摸得着的具体的事务。
- 关系:类是对象的模版,对象是类的实例
- 类的定义
public class Dog {
// 静态属性
String name;//名称
int age;//年龄
// 动态属性 行为 方法
public void sayHello() {
System.out.println("我的名字是" + name + ",我今年" + age + "岁了");
}
}
- 类的调用
package day08.t01;
import day08.t01.Dog;
public class T01 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name="小黑";
dog.age=9;
dog.sayHello();
}
}
- 简单登录demo
用户自定义的类型也是一种数据类型
- 对象数组:
UserInfo[] users = new UserInfo[50];
- 在java中需要判定两个字符串是否相同,得使用
equals()
。 - String,数组,以及自定义类都是引用类型。
package day08.t03;
//定义一个用户类
//用户定义的类也是一种类型,属于引用类型
public class UserInfo {
String username;
String pssword;//密码
}
登录代码
package day08.t03;
import java.util.Scanner;
public class T01 {
public static void main(String[] args) {
// 写一个面向对象的登录程序
// users数组的每一项都是一个用户对象
UserInfo[] users = new UserInfo[50];
// 创建一个UserInfo的对象
UserInfo info = new UserInfo();
info.username = "fly";
info.pssword = "123456";
users[0] = info;
// 用户输入的用户名
Scanner input = new Scanner(System.in);
System.out.println("请输入用户名:");
String uname = input.next();
// 用户输入的密码
System.out.println("请输入密码:");
Scanner upwd = new Scanner(System.in);
String pwd = upwd.next();
// 默认登录失败
boolean flag = false;
// 如何判定用户是否登录成功
for (int i = 0; i < users.length; i++) {
// 在java中判定两个字符串是否相等,使用equals()
if (users[i] != null && users[i].username.equals(uname) && users[i].pssword.equals(pwd)) {
flag = true;
break;
}
}
if(flag){
System.out.println("登录成功~");
}else{
System.out.println("登录失败!");
}
}
}
5. 全局变量(成员变量)与局部变量
- 在方法体中声明的变量叫做:局部变量。在方法中定义的变量,出了这个方法
{}
他就死亡了。方法结束后内存空间就会结束和释放。 - 在方法体外声明的变量叫做:全局变量。全局变量在类中定义的变量,他不属于任何一个方法。所有的方法都可以共性(读取值,修改值),并且全局变量不赋初值,系统会给默认值。
6. 类的方法
6.1 带参方法
6.2 数组作为参数
6.3 对象作为参数
目录结构如下:
T06代码如下:
package day09.t06;
import java.util.Scanner;
public class T06 {
public static void menu() {
System.out.println("欢迎来到图书管理系统~");
System.out.println("1、图书列表");
System.out.println("2、添加图书");
System.out.println("0、退出系统");
System.out.println("请输入对应的操作:输入数字既可");
}
public static void main(String[] args) {
BookManger bookManger = new BookManger();
bookManger.initBoooks();
menu();
Scanner input = new Scanner(System.in);
int num = input.nextInt();
while (num != 0) {//0退出程序
if (num == 1) {
bookManger.booklist();
menu();
num = input.nextInt();
} else if (num == 2) {
// 添加图书
Book book = new Book();
System.out.println("这里是添加图书界面");
System.out.println("请输入图书名称");
book.bookname = input.next();
System.out.println("请输入图书作者");
book.bookauthor = input.next();
System.out.println("请输入图书价格");
book.price = input.nextInt();
boolean flag = bookManger.addBook(book);
if (flag == true) {
System.out.println("添加成功~");
} else {
System.out.println("添加失败!");
}
menu();
num = input.nextInt();
} else if (num == 0) {
break;
}
}
System.out.println("感谢使用该系统");
}
}
BookManger代码如下:
package day09.t06;
public class BookManger {
// 维护一个数组,数组的类型,图书类型,对象数组
Book[] books = new Book[50];
public void initBoooks() {
// 构建一个图书对象
Book book = new Book();
book.bookname = "唐诗";
book.bookauthor = "李白";
book.price = 35;
// 图书对象和数组books进行关联绑定
books[0] = book;
Book book2 = new Book();
book2.bookname = "宋词";
book2.bookauthor = "辛弃疾";
book2.price = 36;
books[1] = book2;
}
// book[0].bookname
//图书列表
public void booklist() {
System.out.println("这是图书列表");
System.out.println("书名\t\t\t\t作者\t\t价格");
for (int i = 0; i < books.length; i++) {
if(books[i]!=null){
System.out.println(books[i].bookname + "\t\t"
+ books[i].bookauthor + "\t\t" + books[i].price
);
}
}
}
// 添加图书的方法
public boolean addBook(Book book) {
boolean flag=false;
for (int i = 0; i < books.length; i++) {
// 判断对象是否为空,和null进行比较
if (books[i] == null) {
books[i] = book;
flag=true;//添加成功~
break;
}
}
return flag;
}
}
7. 抽象和封装
7.1 类的提炼
从现实生活中总结出多种相同物种,具有的相同的特性(属性+行为)提炼到一个容器里,给这个类起一个名字,名字就是类
-
- 发现类(Dog)
-
- 发现类的属性(毛色,品种)
- 3.发现类的方法(跑,叫)
设计优于编码
构造方法:主要完成对象的创建工作
方法重载(overload)
:有多个方法,他们实现的功能相同(不用为起方法名而头疼),方法名称相同,但是参数列表不同。
包含三重含义:
- 参数的个数不同
- 参数的类型不同
- 参数的顺序不同
与返回值与访问修饰符无关
个数相同,类型不同,也可以方法重载。
普通方法可以实现重载,构造方法也可以重载。他们也可以构成重载的条件是他们的参数的顺序不同。如下:
7.2 static
- 直接使用类名直接访问类的属性和方法
在类中,用static声明的成员变量为静态成员变量,也成为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。
这里要强调一下:
- static修饰的成员变量和方法,从属于类
- 普通变量和方法从属于对象
- 静态方法不能调用非静态成员,编译会报错
static关键字的用途 一句话描述就是:方便在没有创建对象的情况下进行调用(方法/变量)。
显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能。
静态成员变量占用的内存是静态存储区,而且一个成员一旦变成静态的,他就是类本身所有,只有一份和对象没有关系了。它会一直生存到程序结束。所以不能将所有的变量都定义到静态存储区。
- 静态代码块 JVM加载类时,加载静态代码块
- 如果有多个静态块,按顺序加载
- 每个静态代码块只会执行一次
静态方法中,不能访问非静态的
static变量和传统的类属性变量有什么区别吗?
主要有以下几点:
- static修饰的变量是属于整个类所有,而不是某个对象所有。
- static修饰的变量可以被所有对象所共享,普通的类变量只能被定义该变量的对象共享。
- static修饰的变量可以直接用类名调用,而普通的类变量则需要通过实例调用。
7.3 封装
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。
数据被保护在类的内部,尽可能地隐藏内部的实现细节,只保留一些对外接口使之与外部发生联系。
其他对象只能通过已经授权的操作来与这个封装的对象进行交互。也就是说用户是无需知道对象内部的细节(当然也无从知道),但可以通过该对象对外的提供的接口来访问该对象。
使用封装有 4 大好处:
- 1、良好的封装能够减少耦合。
- 2、类内部的结构可以自由修改。
- 3、可以对成员进行更精确的控制。
- 4、隐藏信息,实现细节。
- 使用封装的过程
- 将属性的可见性,设置为private
- 创建公有的getter和seteer方法
- 在getter和setter方法中加入判断语句
2.封装的两种体现
- 一个类中可以出现成员变量和方法
- 将私有的成员变量封装公有的get和set方法
案例练习,实现一个Car类,帮助理解
package day10.t07;
public class T07 {
public static void main(String[] args) {
Car car = new Car("吉利", "星越", 2024);
car.setMile(200);
car.show();
}
}
package day10.t07;
public class Car {
// 属性
// 品牌
String brand;
// 型号
String model;
// 生产年份
int year;
// 行驶的里程数
private int mile;
public int getMile() {
return mile;
}
public void setMile(int mile) {
this.mile = mile;
}
// 两个构造方法
public Car() {
}
//带三个参数的构造
public Car(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
}
public void show() {
System.out.println("车的品牌:" + this.brand);
System.out.println("车的型号:" + this.model);
System.out.println("车的生产年份:" + this.year);
System.out.println("车的里程数:" + this.mile);
}
}
- 封装
封装是把数据和操作数据的方法封装在一起,将对象的属性和行为封装到一个对象中,是面向对象编程的一个基本特性。
- 继承
继承是指一个类可以从另一个已存在的类中继承其属性和行为,也可以在继承的基础上增加自己特有的属性或行为,使得子类具有超越父类的功能。
- 多态
多态是指一个事物可以具有多种形态,即一个对象可以根据不同的情况具有不同的形态,也就是说在不同的时刻可以表现出不同的行为。
8. 常用快捷键
- IntelliJ IDEA格式化快捷键: 按下 Ctrl + Alt + L 格式化代码。
- 快捷键
- sout 快速生成
System.out.println("");
- psvm快速生成
public static void main(String[] args) {
}
- 快速创建getter和setter,按Alt+enter
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Ctrl系列快捷键
- Ctrl + Y: 删除当前行。
- Ctrl + D: 复制当前行,并插入到下一行。
- Ctrl + W: 选中文本,连续按可以扩大选中范围。
- Ctrl + F: 在当前文件中查找文本。
- Ctrl + R: 查找并替换文本。
- Ctrl + N: 快速搜索和打开类。
- Ctrl + O: 快速重写基类或者接口中的方法。
Alt系列快捷键
- Alt + Enter: 快速提示完成,在代码存在语法问题时,IDEA会提示使用该快捷键自动修正语法。
- Alt + Insert: 快速生成含有任意形参的构造器和私有属性的Getter/Setter等方法。
- Alt + 1: 快速打开或隐藏Project面板。
Shift系列快捷键
- Shift + Enter: 在当前行下面生成一行空行,光标自动移到空行行首。
- Shift + F6: 批量修改变量名,先选中变量名,然后点击快捷键。
Ctrl + Alt系列快捷键
- Ctrl + Alt + L: 快速格式化代码。
- Ctrl + Alt + O: 优化导入的类和包。
- Ctrl + Alt + T: 将选中的代码使用if、while、try/catch等代码块包装起来。
Ctrl + Shift系列快捷键
- Ctrl + Shift + F10: 快速运行当前的程序。
- Ctrl + Shift + J: 快速整合两行代码,将光标所在行和下一行的代码合并成一行。
9. 常用编程规范
package的命名: package 的名字由全部小写的字母组成,例如:com.runoob。
class和interface的命名: class和interface的名字由大写字母开头而其他字母都小写的单词组成,例如:Person,RuntimeException。
class变量的命名: 变量的名字用一个小写字母开头,后面的单词用大写字母开头,例如:index,currentImage。
class 方法的命名: 方法的名字用一个小写字母开头,后面的单词用大写字母开头,例如:run(),getBalance()。
staticfinal变量的命名: static final变量的名字所有字母都大写,并且能表示完整含义。例如:PI,PASSWORD。
参数的命名: 参数的名字和变量的命名规范一致。
数组的命名: 数组应该总是用这样的方式来命名:byte[] buffer。