JavaSE - 基础篇笔记
![](https://img.haomeiwen.com/i21107801/afe625a26b357971.png)
👉 在线笔记:https://du1in9.github.io/javase.github.io/
Day 1 Java 介绍
1. Java 跨平台性
在需要运行 Java 应用程序的操作系统上,安装一个与操作系统对应的 Java 虚拟机 (JVM Java Virtual Machine) 即可。
2. JDK 的组成
![](https://img.haomeiwen.com/i21107801/033227557c2c3f21.png)
3. IDEA 项目结构介绍
- project(项目、工程)
- module(模块)
- package(包)
- class(类)
Day 2 Java 基础语法
1. 关键字和字面量
Java 中的关键字,已经被赋予了特殊的涵义,这些单词不允许使用
![](https://img.haomeiwen.com/i21107801/b2cdced4b15cb082.png)
![](https://img.haomeiwen.com/i21107801/00af67c4683354b6.png)
2. 变量的介绍
变量就是内存中的存储空间,空间中存储着经常发生改变的数据
![](https://img.haomeiwen.com/i21107801/4487bce48555cdfd.png)
3. 基本数据类型
数据类型 | 关键字 | 内存占用 | 取值范围 |
---|---|---|---|
整数 | byte | 1 | -128~127 |
short | 2 | ||
int (默认) | 4 | ||
long | 8 | ||
浮点数 | float | 4 | |
double (默认) | 8 | ||
字符 | char | 2 | |
布尔 | boolean | 1 |
使用思路
- 整数类型 : 首选int, 如果发现int装不下了, 将类型换成long, 定义long类型变量需要加入L的标识
- 小数类型 : 首选double, 非要用float类型, 需要加入F标识
4. Scanner 键盘录入
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) {
// 1. 召唤Scanner精灵
Scanner sc = new Scanner(System.in);
// 2. 键盘录入姓名
String name = sc.next();
// 3. 键盘录入年龄
int age = sc.nextInt();
// 4. 键盘录入性别
String gender = sc.next();
// 5. 键盘录入身高
double height = sc.nextDouble();
// 6. 键盘录入婚姻状况
boolean flag = sc.nextBoolean();
System.out.println(name);
System.out.println(age);
System.out.println(gender);
System.out.println(height);
System.out.println(flag);
}
}
5. 字符串拼接操作
当 + 操作中,遇到了字符串,这时 + 就是字符串连接符,而不是算术运算。
System.out.println("5+5="+(5+5));
Day 3 Java 运算符
1. 自增自减运算符
int a = 3;
// 4 + 4 + 50
int b = (++a) + (a++) + (a * 10);
System.out.println("a=" + a); // 5
System.out.println("b=" + b); // 58
2. 类型转换
- 隐式类型转换
-
基本的隐式转换
把一个取值范围小的数值或者变量,赋值给另一个取值范围大的变量
-
运算中的隐式转换
取值范围小的数据,和取值范围大的数据进行运算,小的会先提升为大的之后,再进行运算
byte short char 三种数据在运算的时候,都会提升为int,然后再进行运算
byte aa = 10;
byte bb = 20;
int cc = aa + bb;
- 强制转换
把一个取值范围大的数值或者变量,赋值给另一个取值范围小的变量
不允许直接赋值,需要加入强制转换
int num = 130;
byte result = (byte)num;
System.out.println(result); // -126
3. 原码反码补码
![](https://img.haomeiwen.com/i21107801/f4560ec794fa0bc8.png)
![](https://img.haomeiwen.com/i21107801/935040d22597fb00.png)
常量优化机制
// Java存在常量优化机制 : 在编译的时候 (javac) 就会将3和4这两个字面量进行运算.
// 产生的字节码文件 : byte b = 7; 所以代码不会报错
byte b = 3 + 4;
4. 赋值运算符
扩展赋值运算符, 内部自带强转效果
double a = 12.3;
int b = 10;
b += a; // b = 22;
5. 逻辑运算符
&(与): 范围性的判断查找
if(score >= 90 & score <= 100)
|(或): 多个条件任选其一
if(id == 3 | id == 5 | id == 12)
!(非): 对一段逻辑整体做取反操作
if( ! (id == 3 | id == 5 | id == 12) )
^(异或): 相同为false, 不同为true
短路逻辑运算符 :
&& : 具有短路效果, 左边为false, 右边不执行了; 左边为true, 右边要继续执行
|| : 具有短路效果, 左边为true, 右边不执行了; 左边为false, 右边要继续执行
为了节省效率,常用的逻辑运算符: && 、|| 、! 。
Day 4 Java 方法
1. 方法
![](https://img.haomeiwen.com/i21107801/437589a1e39f57cc.png)
2. 内存图解
![](https://img.haomeiwen.com/i21107801/26899d50ef0ef457.png)
![](https://img.haomeiwen.com/i21107801/d2fdcf0eb00deabd.png)
![](https://img.haomeiwen.com/i21107801/a11c16e0f7d7387e.png)
![](https://img.haomeiwen.com/i21107801/874b016b388d2d1c.png)
3. 方法重载
同一个类中,方法名相同,参数不同的方法。参数不同:个数不同、类型不同、顺序不同
注意:识别方法之间是否是重载关系,只看方法名和参数,跟返回值无关。
![](https://img.haomeiwen.com/i21107801/3d7ce8b8cede2cf3.png)
方法重载的好处:不用记忆过多繁琐的方法名字
Day 5 Java 流程控制语句
1. 三种循环语句的区别
for 循环 和 while循环(先判断后执行)
do...while (先执行后判断)
for 循环中,控制循环的变量,在 for 循环结束后,就不能再次被访问到了
while 循环中,控制循环的变量,在 while 循环结束后,该变量还可以继续使用
![](https://img.haomeiwen.com/i21107801/057de96ea8917075.png)
2. Random 随机数
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
randomTest();
}
public static void randomTest() {
Random r = new Random();
// 需求: 产生11个20~80之间的随机数
for (int i = 1; i <= 11; i++) {
int num = r.nextInt(61) + 20;
System.out.println(num);
}
}
}
Day 6 Java 数组
1. 数组的静态初始化
完整格式 : 数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3...};
简化格式 : 数据类型[] 数组名 = {元素1, 元素2, 元素3...};
/*
打印数组名 :
[I@776ec8df
@ : 分割符
[ : 当前空间, 是数组类型的
I : 当前数组类型, 是int类型
776ec8df : 数组的十六进制内存地址
*/
int[] arr1 = {11, 22, 33};
double[] arr2 = {11.1, 22.2, 33.3};
System.out.println(arr1);
System.out.println(arr2);
2. 数组的动态初始化
格式: 数据类型[] 数组名 = new 数据类型[长度];
/*
默认值的分类 :
整数 : 0
小数 : 0.0
布尔 : false
字符 : '\u0000' ---> Unicode字符
引用数据类型 : null
引用数据类型 : 数组, 类, 接口
String : 类
*/
String[] arr = new String[3];
3. 两者区别
动态初始化: 手动指定长度, 系统分配默认初始化值
静态初始化: 手动指定元素, 系统会根据元素的个数, 计算出数组的长度
/*
两种初始化的使用选择 :
1. 静态初始化: 如果要操作的数据, 需求中已经明确给出了, 直接静态初始化
需求: 已知班级学生成绩为 100 100 90 20 100, 找出最高分
int[] arr = {100,100,90,20,100};
2. 动态初始化: 只明确元素个数, 不明确具体数值
需求1: 键盘录入5个学生成绩, 找出最高分
需求2: 产生10个1~100之间的随机数, 找出最小值
*/
4. 内存图解
![](https://img.haomeiwen.com/i21107801/fb5538dcffecc365.png)
![](https://img.haomeiwen.com/i21107801/55b75cd2abf8cb54.png)
方法的参数传递问题 :
- 基本数据类型: 传递的是数据值
![](https://img.haomeiwen.com/i21107801/0b4645e4a8ba3c32.png)
- 引用数据类型: 传递的是地址值
![](https://img.haomeiwen.com/i21107801/52b454e8233ce9e6.png)
5. 数组常见问题
-
数组索引越界异常 : ArrayIndexOutOfBoundsException
原因: 访问了不存在的索引
-
空指针异常 : NullPointerException
原因: 当引用数据类型变量被赋值为 null 之后,地址的指向被切断,还继续访问堆内存数据,就会引发空指针异常
6. 二维数组
细节: 二维数组在存储一维数组的时候, 具体存储的是一维数组的地址值
一维数组存入二维数组内存图解:
![](https://img.haomeiwen.com/i21107801/5f7ed6cf330af5a1.png)
![](https://img.haomeiwen.com/i21107801/1d7bcc77935e81e5.png)
7. 综合案例
- 数据交换
// 面试题: 实现两个变量的数据交换, 不允许定义第三方变量
// 利用异或的特点: 一个数字, 被另外一个数字异或两次, 该数本身不变
int a = 10;
int b = 20;
a = a ^ b; // a = 10 ^ 20;
b = a ^ b; // b = 10 ^ 20 ^ 20; b = 10
a = a ^ b; // a = 10 ^ 20 ^ 10; a = 20
- 数组反转
private static void reverseArray1(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
private static void reverseArray2(int[] arr) {
for(int i = 0, j = arr.length - 1; i < j; i++, j--){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
- 随机产生验证码
package com.itheima.test;
import java.util.Random;
import java.util.Scanner;
public class Test7 {
// 注意事项: 打印字符类型数组名, 不会看到地址值, 而是元素的内容
public static void main(String[] args) {
char[] chs = getContents();
String checkCode = getCheckCode(chs);
System.out.println(checkCode);
}
private static String getCheckCode(char[] chs) {
Random r = new Random();
String checkCode = "";
for(int i = 1; i <= 5; i++){
int j = r.nextInt(chs.length);
checkCode += chs[j];
}
return checkCode;
}
private static char[] getContents() {
char[] chs = new char[26 + 26 + 10];
int index = 0;
for(char c = 'a'; c <= 'z'; c++){
chs[index] = c;
index++;
}
for(char c = 'A'; c <= 'Z'; c++){
chs[index] = c;
index++;
}
for(char c = '0'; c <= '9'; c++){
chs[index] = c;
index++;
}
return chs;
}
}
Day 7 Java 面向对象
1. 面向对象介绍
面向对象:并不是一个技术,而是一种编程的指导思想
为什么要学习面向对象?
因为生活中,我们解决问题时,就是采用这种指导思想去解决的所以,我们写程序去解决问题时,如果也能采用这种指导思想就会使编程变得非常简单,程序也便于人理解
![](https://img.haomeiwen.com/i21107801/4ef223ba41b7cdfa.png)
2. 类和对象
- 类 : 一组相关属性和行为的集合, 将其看做为是对象的设计图.
- 对象 : 是根据设计图(类), 创建出来的实体
/*
类的组成:
属性(名词): 在代码中使用成员变量表示, 成员变量跟之前定义变量的格式一样, 只不过位置发生了改变, 类中方法外.
行为(动词): 在代码中使用成员方法表示, 成员方法跟之前定义方法的格式一样, 只不过需要去掉 static 关键字
*/
public class Student {
// 属性: 姓名, 年龄
String name;
int age;
// 行为: 学习, 吃饭
public void study() {
int a = 10;
System.out.println(name);
System.out.println("学生学习...");
}
public void eat() {
System.out.println(name);
System.out.println("学生吃饭...");
}
}
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 23;
System.out.println(stu1.name);
System.out.println(stu1.age);
stu1.study();
stu1.eat();
3. 对象内存图
![](https://img.haomeiwen.com/i21107801/57ec9f51163db4a8.png)
![](https://img.haomeiwen.com/i21107801/58ed9a03ffed4662.png)
![](https://img.haomeiwen.com/i21107801/eb09eed8256025ed.png)
4. 成员变量和局部变量
区别 | 成员变量 | 局部变量 |
---|---|---|
类中位置不同 | 方法外 | 方法中 |
初始化值不同 | 有默认初始化值 | 没有,使用之前需要完成赋值 |
内存位置不同 | 堆内存 | 栈内存 |
生命周期不同 | 随着对象的创建而存在,随着对象的消失而消失 | 随着方法的调用而存在,随着方法的运行结束而消失 |
作用域 | 在自己所归属的大括号中 | 在自己所归属的大括号中 |
5. this关键字
- 当局部变量和成员变量重名的时候, Java 使用的是 : 就近原则
- this 关键字的作用是 : 调用本类成员
- this.本类成员变量 : 如果不涉及变量重复, this.可以省略
- this.本类成员方法 : 没有前提条件 this.可以直接省略
- 什么是 this 关键字呢 ? 代表当前类对象的引用 (地址)
/*
this介绍 : 代表当前类对象的引用(地址)
- 谁来调用我, 我就代表谁.
- 哪一个对象调用方法, 方法中的this, 代表的就是哪一个对象.
stu1.print() ----> this ---> stu1的地址
stu2.print() ----> this ---> stu2的地址
*/
public class Student {
String name;
public void sayHello(String name) {
System.out.println(name);
System.out.println(this.name);
method();
}
public void method(){
System.out.println(name);
}
public void print(){
System.out.println("print方法中打印this关键字 ---> " + this);
}
}
6. 构造方法
- 构造方法的创建
如果没有定义构造方法,系统将给出一个默认的无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法 - 构造方法的重载
构造方法也是方法,允许重载关系出现 - 推荐的使用方式
无参数构造方法,和带参数构造方法,都自己手动给出
public class Student {
String name;
int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Student stu1 = new Student("张三", 23);
Student stu2 = new Student("李四",24);
Student stu3 = new Student();
7. 封装和权限修饰符
权限修饰符 :
- private : 同一个类中
- (default) : 同一个类中, 同一个包中
- protected : 同一个类中, 同一个包中, 不同包的子类 (TODO : 继承)
- public : 任意位置访问
public class Student {
private int age;
public void setAge(int age) {
if (age >= 1 && age <= 120) {
this.age = age;
} else {
System.out.println("年龄有误, 请检查是否是1~120之间");
}
}
public int getAge() {
return age;
}
}
Student stu = new Student();
stu.setAge(23);
int age = stu.getAge();
System.out.println(age);
8. JavaBean
实体类的应用场景是什么?
实体类只负责数据存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。
快捷键:右键 → Ptg To JavaBean
9. 综合案例
import com.itheima.domain.Movie;
import java.util.Scanner;
public class MovieService {
private Movie[] movies;
private Scanner sc = new Scanner(System.in);
public MovieService(Movie[] movies) {
this.movies = movies;
}
public void start() {
lo:
while (true) {
System.out.println("----------电影信息系统----------");
System.out.println("请输入您的选择:");
System.out.println("1. 查询全部电影信息");
System.out.println("2. 根据id查询电影信息");
System.out.println("3. 退出");
int choice = sc.nextInt();
switch (choice) {
case 1:
queryMovieInfos();
break;
case 2:
queryMovieInfoById();
break;
case 3:
System.out.println("感谢您的使用, 再见!");
break lo;
default:
System.out.println("您的输入有误, 请检查");
break;
}
}
}
private void queryMovieInfoById() {
System.out.println("请输入您要查询的电影编号:");
int id = sc.nextInt();
for (int i = 0; i < movies.length; i++) {
Movie movie = movies[i];
if(movie.getId() == id){
System.out.println(movie.getId() + "---" + movie.getTitle() + "---" + movie.getTime()
+ "---" + movie.getScore() + "---" + movie.getArea() + "---"
+ movie.getType() + "---" + movie.getDirector() + "---" + movie.getStarring());
return;
}
}
System.out.println("您输入的编号不存在, 请检查!");
}
private void queryMovieInfos() {
for (int i = 0; i < movies.length; i++) {
Movie movie = movies[i];
System.out.println(movie.getTitle() + "---" + movie.getScore());
}
}
}
Movie movie1 = new Movie(1, "东八区的先生们", "2022", 2.1, "中国大陆", "剧情 喜剧", "夏睿", "张翰 王晓晨");
Movie movie2 = new Movie(2, "上海堡垒", "2019", 2.9, "中国大陆", "爱情 战争 科幻", "滕华涛", "鹿晗 舒淇");
Movie movie3 = new Movie(3, "纯洁心灵·逐梦演艺圈", "2015", 2.2, "中国大陆", "剧情 喜剧", "毕志飞", "朱一文 李彦漫");
Movie[] movies = {movie1, movie2, movie3};
MovieService movieService = new MovieService(movies);
movieService.start();
Day 8 Java 字符串
1. API 帮助文档
API帮助文档的使用流程
- 在索引位置搜索自己要查看的类
- 看包 : 是不是java.lang包 (核心包), 不需要编写导包代码 (import)
- 看这个类的介绍 : 搞清楚这个类的作用
- 看这个类的构造方法 : 为了将该类的对象, 创建出来
- 看这个类的成员方法 (方法摘要) : 方法名、参数、返回值、介绍
/*
Scanner键盘录入字符串 :
String next() : 遇到了空格, 或者是tab键就不再录入了
String nextLine() : 以回车作为录入的结束标记
弊端:
1. next() : 数据可能录入不完整
2. nextLine() : 之前调用过nextInt(), nextDouble()..., nextLine()方法, 就不干活了
解决方案: 不用解决
Scanner : 采集用户信息 (只在学习过程用的到)
目前的使用方案:
需求如果要键盘录入字符串
如果所有的数据, 全部都是字符串, 直接nextLine();
如果数据除了字符串, 还有其他类型, 需要调用next()方法
*/
2. String 类的特点
-
Java 程序中所有双引号字符串, 都是String这个类的对象
-
字符串一旦被创建, 就不可更改, 字符串内容不可改变
如果想要更改, 只能使用新的对象, 做替换
-
String字符串虽然不可改变, 但是可以被共享
字符串常量池: 当我们使用双引号创建字符串对象时, 会检查常量池中是否存在该数据
String s1 = "abc";
String s2 = "abc";
System.out.println("def".toUpperCase()); // DEF
System.out.println(s1 == s2); // true
3. String 类常见构造方法
- public String() : 创建一个空白字符串, 里面不含任何内容
- public String(char[] chs) : 根据传入的字符数组, 创建字符串对象
- public String(String original) : 根据传入的字符串, 来创建字符串对象
String s1 = new String();
char[] chs = {'a','b','c'};
String s2 = new String(chs);
String s3 = new String("abc");
/*
1. 打印对象名, 会看到对象的内存地址, 这里打印字符串对象, 为什么没有看到地址值
回答: 暂不解释
TODO: 面向对象(继承), 方法重写, Object类, toString方法
2. 这三个构造方法, 创建字符串对象, 都没有双引号直接创建来的方便.
String s = "abc";
-----------------------------------------------------------------
字符串对象, 两种创建方式的区别
1. 双引号直接创建
2. 通过构造方法创建
*/
4. String 常见面试题
![](https://img.haomeiwen.com/i21107801/cb03a3e22c649e7e.png)
![](https://img.haomeiwen.com/i21107801/540fca0069649b9d.png)
![](https://img.haomeiwen.com/i21107801/91d0f7c81527400b.png)
5. String 字符串比较、遍历
/*
public boolean equals(Object anObject) 将此字符串与指定的对象比较
public boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写
*/
String s1 = "abc";
String s2 = new String("abc");
String s3 = "ABC";
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // false
System.out.println(s1.equalsIgnoreCase(s3)); // true
/*
String类用于遍历的方法:
public char[] toCharArray() 将此字符串转换为一个新的字符数组
public char charAt(int index) 返回指定索引处的 char 值
public int length() 返回此字符串的长度
*/
private static void print1(String s) {
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
}
private static void print2(String s) {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
System.out.println(c);
}
}
6. String 字符串截取、替换、切割
/*
String类的截取方法 :
public String substring(int beginIndex) : 根据传入的索引开始做截取, 截取到字符串的末尾
public String substring(int beginIndex, int endIndex) : 根据传入的开始和结束索引, 对字符串做截取
注意: 截取出来的内容, 是作为新的字符串返回, 别忘记找变量接收
*/
String s = "itheima";
String result1 = s.substring(0, 2); // it
String result2 = s.substring(2); // heima
/*
String类的替换方法 :
public String replace(CharSequence target, CharSequence replacement) :
*/
String s = "itheima";
String result = s.replace("heima", "baima"); // itbaima
/*
String类的切割方法 :
public String[] split(String regex) : 根据传入的字符串作为规则, 切割当前字符串
建议: 先正常指定切割规则, 后来发现没有得到自己要的效果, 就可以尝试在规则前面, 加入 \\
*/
String s1 = "192,168,1,1";
String s2 = "192.168.1.1";
String[] sArr1 = s1.split(",");
String[] sArr2 = s2.split("\\.");
7. StringBuilder 的引入
StringBuilder的作用 : 提高字符串的操作效率
![](https://img.haomeiwen.com/i21107801/7d3f2c59afc2a1fa.png)
![](https://img.haomeiwen.com/i21107801/d4d71c7c8357381c.png)
// 获取1970年1月1日0时0分0秒到现在所经历过的毫秒值 (1秒 = 1000毫秒)
long t1 = System.currentTimeMillis();
String s1 = "";
for(int i = 1; i <= 100000; i++) {s1 += i;}
long t2 = System.currentTimeMillis();
System.out.println(t2 - t1); // 2804
long t3 = System.currentTimeMillis();
StringBuilder s2 = new StringBuilder();
for(int i = 1; i <= 100000; i++) {s2.append(i);}
long t4 = System.currentTimeMillis();
System.out.println(t4 - t3); // 10
8. StringBuilder 构造方法
/*
StringBuilder的介绍 :
1. 一个可变的字符序列
2. StringBuilder是字符串缓冲区, 将其理解是容器, 可以存储任意数据类型, 但是只要进入到这个容器, 全部变成字符串.
StringBuilder的构造方法 :
public StringBuilder() : 创建一个空白的字符串缓冲区(容器), 其初始容量为16个字符
public StringBuilder(String str) : 创建一个字符串缓冲区(容器), 容器在创建好之后, 就会带有参数的内容
*/
StringBuilder sb = new StringBuilder("abc"); // abc
sb.append(100.234); // abc100.234
sb.append('锅'); // abc100.234锅
sb.append(false); // abc100.234锅false
9. StringBuilder 常用成员方法
/*
1. public StringBuilder append(任意类型) : 添加数据, 并返回对象自己
2. public StringBuilder reverse() : 将缓冲区中的内容, 进行反转
3. public int length() : 返回长度
4. public String toString() : 将缓冲区的内容, 以String字符串类型返回
*/
StringBuilder sb = new StringBuilder();
sb.append("红色").append("绿色").append("蓝色"); // 红色绿色蓝色
sb.reverse(); // 色蓝色绿色红
String[] sArr = sb.toString().split("色"); // 蓝, 绿, 红
Day 9 Java 集合基础
1. 集合介绍
![](https://img.haomeiwen.com/i21107801/2a376925cce3cff3.png)
集合和数组的使用选择
- 数组: 存储的元素个数固定不变
- 集合: 存储的元素个数经常发生改变
![](https://img.haomeiwen.com/i21107801/b9ec489726c7e512.png)
2. 集合的创建和添加
/*
ArrayList集合的使用:
细节: 创建String, StringBuilder, ArrayList类的对象, 打印对象名, 都没有看到地址值, 而是元素内容
1. 构造方法 :
public ArrayList() : 创建一个空的集合容器
2. 集合容器的创建细节 :
ArrayList list = new ArrayList();
现象: 可以添加任意类型数据
弊端: 数据不够严谨
ArrayList<String> list = new ArrayList<>();
<> : 泛型
目前: 使用泛型, 可以对集合中存储的数据, 进行类型限制
细节: 泛型中, 不允许编写基本数据类型
问题: 那我要是想集合中, 存储 整数, 小数, 字符... 这些数据, 怎么办呢?
解决: 使用基本数据类型, 所对应的包装类
*/
ArrayList<Double> list1 = new ArrayList<>();
list1.add(11.1);
list1.add(22.2);
list1.add(33.3);
3. 集合的增删改查
/*
1. 增 :
public boolean add(E e) : 将指定的元素添加到此列表的尾部
public void add(int index, E element) : 在指定索引位置, 添加对应的元素 (插队)
2. 删
public E remove(int index) : 根据索引做删除, 返回被删除掉的元素
public boolean remove(Object o) : 根据元素做删除, 返回是否删除成功的状态
3. 改
public E set(int index, E element) : 修改指定索引位置, 为对应的元素, 返回被覆盖掉的元素
------------------------------------------------------------------------------------------
以上方法, 返回值通常不做接收
4. 查
public E get(int index) : 根据索引, 获取集合中的元素
public int size() : 返回集合中元素的个数
*/
ArrayList<String> list = new ArrayList<>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
list.add(0, "张三4");
System.out.println(list);
boolean flag = list.remove("李四");
System.out.println(list);
String result = list.set(1, "李四");
System.out.println(list);
String s = list.get(2);
System.out.println(s);
System.out.println(list.size());
4. 集合的遍历
//需求: 创建一个存储学生对象的集合,存储3个学生对象;在控制台, 展示出年龄低于18岁的学生信息
public static void main(String[] args) {
Student stu1 = new Student("张三",23);
Student stu2 = new Student("李四",14);
Student stu3 = new Student("王五",15);
ArrayList<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
list.add(stu3);
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
if(stu.getAge() < 18){
System.out.println(stu.getName() + "---" + stu.getAge());
}
}
5. 内存图解
![](https://img.haomeiwen.com/i21107801/15e614236fbb5e9b.png)
6. 集合删除数据
/*
需求: 创建一个存储String的集合,内部存储(test,张三,李四,test,test)字符串
删除所有的test字符串,删除后,将集合剩余元素打印在控制台
总结: 在遍历集合的过程中, 有删除操作
1. 正序遍历 : 不要忘记 --操作
2. 倒序遍历 : 不需要 --操作
*/
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if("test".equals(s)){
list.remove(i);
i--;
}
}
for(int i = list.size() - 1; i >= 0; i--){
String s = list.get(i);
if("test".equals(s)){
list.remove(i);
}
}
7. 学生管理系统
- 演示和准备动作
public class Student {
private int id;
private String name;
private int age;
private String date;
// ...(JavaBean)
}
ArrayList<Student> students = new ArrayList<Student>();
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("----------- 欢迎来到学生管理系统 ---------");
System.out.println(" 1 添加学生");
System.out.println(" 2 修改学生");
System.out.println(" 3 删除学生");
System.out.println(" 4 查看学生");
System.out.println(" 5 退出");
int choice = sc.nextInt();
switch (choice){
case 1:
addStudent(students);
break;
case 2:
setStudent(students);
break;
case 3:
removeStudent(students);
break;
case 4:
getStudent(students);
break;
case 5:
System.out.println("感谢您的使用,再见!");
System.exit(0);
break;
default:
System.out.println("您的输入有误,请再次输入。");
break;
}
}
- 查看功能
private static void getStudent(ArrayList<Student> students) {
System.out.println("学号\t姓名\t年龄\t生日");
for (int i = 0; i < students.size(); i++) {
Student stu = students.get(i);
System.out.println(stu.getId()+"\t"+stu.getName()+"\t"+stu.getAge()+"\t"+stu.getDate());
}
}
- 删除功能
private static void removeStudent(ArrayList<Student> students) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生id:");
int id = sc.nextInt();
for (int i = 0; i < students.size(); i++) {
if(id == students.get(i).getId()){
students.remove(i);
return;
}
}
}
- 修改功能
private static void setStudent(ArrayList<Student> students) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生id:");
int id = sc.nextInt();
for (int i = 0; i < students.size(); i++) {
Student stu = students.get(i);
if(id == stu.getId()){
System.out.println("请输入学生name:");
String name = sc.next();
System.out.println("请输入学生age:");
int age = sc.nextInt();
System.out.println("请输入学生date:");
String date = sc.next();
stu.setName(name);
stu.setAge(age);
stu.setDate(date);
return;
}
}
}
- 添加功能
private static void addStudent(ArrayList<Student> students) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生id:");
int id = sc.nextInt();
System.out.println("请输入学生name:");
String name = sc.next();
System.out.println("请输入学生age:");
int age = sc.nextInt();
System.out.println("请输入学生date:");
String date = sc.next();
students.add(new Student(id, name, age, date));
}
参考链接:https://www.bilibili.com/video/BV1Fv4y1q7ZH?p=1&vd_source=ed621eaa6bcf9bf6acb7d0527c30489a