适合有其他语言基础想快速入门JavaSE的。用的资料是 Java入门基础视频教程 ,从中摘取了笔者认为与其他语言不同或需要重点学习的内容
本篇中讲解的都是JavaSE的基础语法需要深刻理解,API中的一些方法不需要强记,先理解即可
day01 Java基础入门
二、Java快速入门
2.1 JDK下载和安装
这里所说的Java开发环境,实际上就是Java官方提供的一个软件,叫做JDK(全称是Java Develop Kit),翻译过来意思就是Java开发工具包。我们先要到官网上去下载JDK,然后安装在自己的电脑上,才可以在自己的电脑上使用JDK来开发Java程序

jdk-17下载地址:
oracle
zulu
下载后还要配置环境变量(后面2.7节提到)

这里笔者下载的是oracle版本的
2.4 Java程序中常见问题
文件扩展名勾选:没有勾选,就会导致你创建的文件是普通的文本文件(.txt)文件,而不是java文件。

2.5 JDK的组成

2.6 Java的跨平台原理
跨平台指的是用Java语言开发的程序可以在多种操作系统上运行
跨平台性的原理是因为在不同版本的操作系统中安装有不同版本的Java虚拟机,Java程序的运行只依赖于Java虚拟机,和操作系统并没有直接关系。从而做到一处编译,处处运行。
2.7 JDK环境变量配置
什么是Path环境变量?
Path环境变量是让系统程序的路径,方便程序员在命令行窗口的任意目录下启动程序;
因此我们需要将JDK配置到Path路径下,方法:把JDK的bin目录配置到Path环境变量下,这样就可以在任意目录下启动javac和java命令来完成编译和运行了
三、Java开发工具
3.2 IDEA编写Java程序
- 第一步:首先得在IDEA中创建一个Project(工程、也叫项目),后面统称为工程。
- 第二步:需要在Project中创建Module(模块),一个工程中可以包含多个模块
- 第三步:需要在Module中新建Package(包),一个模块中可以有多个包
- 第四步:需要在Package中新建Class(类),一个包中可以包含多个类


四、Java基础语法
4.3 变量
变量的作用域:大括号内
在同一个作用域内,不能有两个同名的变量
命名:
2.类名:首字母大写(大驼峰命名)
举例: class Student{}
3.变量名:第二个单词开始首字母大写(小驼峰命名)
举例: double applePrice = 7.5;
day02 数据类型、运算符
一、数据的表示详解
1.1 整数在计算机中的存储原理
前面我们已经知道计算机表示数据是用二进制来的, 这里我又要抛出一个问题来了! 我现在想要在计算机中存储一个整数6,转换为二进制是110,那么计算机中只是存110吗三位数字吗? 其实不是的,计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储。
我们随便找到一个文件,看文件的属性,可以看到文件的大小都是以字节为单位的。
1.2 字符在计算机中的存储原理
字符并不是直接存储的,而是把每一个字符编为一个整数,存储的是字符对应整数的二进制形式。美国人搞了一套字符和整数的对应关系表,叫做ASCII编码表。
ASCII编码表中字符编码的规律:
1.字符0对应48,后面的1,2,3,4...9 对应的十进制整数依次往后顺延
2.字符a对应97,后面的b,c,d,e...z 对应的十进制整数依次往后顺延
3.字符A对应65,后面的B,C,D,E...Z 对应的十进制整数依次往后顺延
需要注意的是,在ASCII编码表中是不包含汉字的。汉字在其他编码表中,后面我们会单独介绍。
1.3 图片视频声音的存储原理
通过上面的学习我们已经知道整数和字符是如何存储的,最终都是要转换为二进制数据的,对吧! 那图片、声音、视频又是如何存储的呢?我们也来了解一下
我们从图片开始,如果你把一张图片不断的放大,你会看到有马赛克的效果。你会发现图片中的每一个细节是由一个一个的小方格组成的,每一个小方格中其实就是一种颜色。任何一种颜色可以使用三原色来表示,简称RGB,其中R(红色),G(绿色),B(蓝色),而RGB中每一种颜色又用一个字节的整数来表示,最小值是0最大值是255
RGB(0,0,0)表示黑色
RGB(255,255,255)表示白色
RGB(255,0,0) 表示红色
RGB(255,255,0) 表示红色和绿色混合为黄色
RGB(255,0,255) 表示红色和蓝色混合为紫色
...
一张图片实际上就是有很多个小方块的颜色组成的,而每一种颜色又是由RGB三原色的整数表示的,整数最终会转换为二进制进行存储。
实际上视频和图片是一样的,把多张图片连续播放,在一秒钟内连续播放24张以上,由于人眼存在视觉暂留现象,人眼感受不到画面切换的时间间隔,就认为是连续的视频了。
了解过物理的同学肯定知道,声音是以波的形式传播的。我们可以把声波在表示在一个坐标系上,然后在坐标系上取一些点,把这些点的坐标值以二进制的形式存储到计算机中,这就是声音的存储原理。
1.5 不同进制在Java程序中的书写格式
System.out.pirntln('a'+1); //98
System.out.pirntln(0b01100001); //97
System.out.pirntln(0141); //97
System.out.pirntln(0x61); //97
二、数据类型详解
Java的数据类型整体上来说分为两大类: 基本数据类型、引用数据类型。
本章节主要学习基本数据类型,基本数据类型一共有4类8种,每一种数据类型占用的内存空间不一样,能够表示的数据范围也不一样。

需要我们注意的是,随便写一个整数或者小数的字面量,它也是有默认数据类型的
- 比如23,它默认就为int类型;如果加上后缀L,则为long类型;
- 比如23.8,它默认为double类型;如果加上后缀F,则为float类型;
// 注意:随便写一个整型字面量,默认是int类型的,73642422442424虽然没有超过long的范围,但是它超过了本身int的范围了。
// 如果希望随便写一个整型字面量是long类型的,需要在其后面加上L/l
long number4 = 73642422442424L;
// 3、字符型;注意这里的字符型可以是中文汉字
char ch1 = 'a';
char ch2 = '中';
char ch3 = '国';
三、数据类型转换
为什么要学习类型转换呢?因为在我们实际开发中可能存在将某种类型变量的值,赋值给另一个类型的变量;也可能存在多种数据类型的数据一起运算的情况。
在以上情况中,其实都会涉及到类型转换。类型转换的形式总体分为2种,一种是自动类型转换,一种是强制类型转换。 这里先学习自动类型转换
3.1 自动类型转换
什么是自动类型转换呢?
答:自动类型转换指的是,数据范围小的变量可以直接赋值给数据范围大的变量
byte a = 12;
int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)
自动类型转换的原理是怎样的?
答:自动类型转换其本质就是在较小数据类型数据前面,补了若干个字节

除了byte和int之间的转换之外,其他类型也可以转换,转换顺序如下图所示

char ch = 'a'; // 'a' 97 => 00000000 01100001
int i = ch; // 发生了自动类型转换了 => 00000000 00000000 00000000 01100001
表达式的自动类型转换
自动类型转换还有另外一种形式,就是表达式的自动类型转换。所谓表达式指的是几个变量或者几个数据一起参与运算的式子。
如果同一个表达式中,出现不同类型的变量或者数据一起运算,这种情况下运算结果是一个什么数据类型呢?需要遵守下面的两条运算规则:
1.多种数据类型参与运算,其结果以大的数据类型为准
2.byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算
byte a = 10;
int b = 20;
long c = 30;
long rs = a + b + c;
System.out.println(rs);
double rs2 = a + b + 1.0;
System.out.println(rs2);
byte i = 10;
short j = 30;
int rs3 = i + j;
System.out.println(rs3);
// 面试笔试题: 即使两个byte运算,结果也会提升为int
byte b1 = 110;
byte b2 = 80;
int b3 = b1 + b2;
System.out.println(b3);
3.2 强制类型转换
前面我们学习了自动类型转换,我们知道可以将数据类型小的数据可以直接赋值给数据范围大的变量。 那反过来,能不能将数据范围大的数据直接赋值给数据范围小的变量呢? 答案是会报错。
什么是强制类型转换
但是你强行将范围大的数据,赋值给范围小的变量也是可以的,这里就需要用到强制类型转换。下面是强制类型转换的格式
目标数据类型 变量名 = (目标数据类型)被转换的数据;
int i = 1500;
byte j = (byte) i;
System.out.println(i); // 1500
System.out.println(j); // -36
double d = 99.5;
int m = (int) d; // 强制类型转换
System.out.println(m); // 99 丢掉小数部分,保留整数部分
强制类型转换的原理
强制类型转换的原理,其实就是强行把前面几个字节砍掉,但是有数据丢失的风险。

四、运算符
3.1 算术运算符
// 目标2:掌握使用+符号做连接符的情况。
int a2 = 5;
System.out.println("abc" + a2); // "abc5"
System.out.println(a2 + 5); // 10
System.out.println("itheima" + a2 + 'a'); // "itheima5a"
System.out.println(a2 + 'a' + "itheima"); // 102itheima 注意'a'是字符不是字符串 5+97
3.3 赋值运算符

扩展的赋值运算符有强制类型转换
问题1:下面的代码否有问题?
byte x = 10;
byte y = 30;
x = x + y; //这句代码有问题,因为两个byte类型数据相加,会提升为int类型;
问题2:下面的代码是否有问题?
byte x = 10;
byte y = 30;
x+=3; //这句代码没有问题,因为这里有隐含的强制类型转换
//x+=3; 等价于 byte x = (byte)(x+y);
3.5 逻辑运算符
逻辑运算符是用来将多个条件放在一起运算,最终结果是true或者false

day03 程序流程控制
一、分支结构
1.2 switch分支
switch 分支的作用,是通过比较值来决定执行哪条分支代码

1.3 switch 注意事项
- 1.表达式类型只能是byte、short、int、char
JDK5开始支持枚举,JDK7开始支持String
不支持double、float、double
- 2.case给出的值不允许重复,且只能是字面量,不能是变量。
- 3.正常使用switch的时候,不要忘记写break,否则会出现穿透现象。
二、循环结构
2.1 for循环——格式和流程

2.3 while循环——格式和流程

2.4 do-while循环——格式和流程

day04 Java数组
二、数组的定义和访问
数组有两种初始化的方式,一种是静态初始化、一种是动态初始化。我们先用静态初始化来学习数组的操作。
2.1 数组的静态初始化
所谓静态初始化指的是:在定义数组时直接给数组中的数据赋值。
1. 静态初始化标准格式:
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};
2. 静态初始化简化格式:
数据类型[] 变量名 = {元素1,元素2,元素3};
定义数组时, 数据类型[] 数组名 也可写成 数据类型 数组名[]
//以下两种写法是等价的。但是建议大家用第一种,因为这种写法更加普遍
int[] ages = {12, 24, 36};
int ages[] = {12, 24, 36}
4.数组在计算机中的基本原理
我们以int[] ages = {12,24,36};这句话为例,看一下这句话到底在计算机中做了那些事情。
- 首先,左边
int[] ages表示定义了一个数组类型的变量,变量名叫ages - 其次,右边
{12,24,36}表示创建一个数组对象,你完全可以把它理解成一个能装数据的东西。这个对象在内存中会有一个地址值[I@4c873330,每次创建一个数组对象都会有不用的地址值。 - 然后,把右边的地址值
[I@4c873330赋值给左边的ages变量 - 所以,ages变量就可以通过地址值,找到数组这个东西。

注意:数组变量名中存储的是数组在内存中的地址,数组是一种引用数据类型。
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
// i的取值 = 0,1,2
System.out.println(ages[i]);
}
2.5 数组的动态初始化
动态初始化不需要我们写出具体的元素,而是指定元素类型和长度就行。格式如下
//数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
下面是动态初始化数组的原理图。我们发现int[] arr 其实就是一个变量,它记录了数组对象的地址值,而且数组中的元素默认值是0。

注意:
使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同。

三、数组在计算机中的执行原理
3.1 数组的执行原理,Java程序的执行原理
前面我们给大家讲过,程序是在内存中执行的。实际上Java程序是把编译后的字节码加载到Java虚拟机中执行的。

Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆。
下面把每一个块内存区域作用介绍一下,我们大致只需要知道每一部分存储什么内容就行。
- 方法区:字节码文件先加载到这里
- 栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
- 堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。(这里区分 数组 和 数组类型的变量arr)
下面是上面案例执行的内存原理如下图所示,按照① ② ③ ④ ⑤ ⑥ 的标记的顺序来看
public class ArrayDemo1 {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
int[] arr = new int[]{11, 22, 33};
System.out.println(arr);
System.out.println(arr[1]);
arr[0] = 44;
arr[1] = 55;
arr[2] = 66;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}

总结一下int a = 10与 int[] arr = new int[]{11,22,33}的区别
- a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。a是一个基本类型变量,存储的是一个数值
- arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值。arr是一个引用类型的变量,存储的是一个地址值
3.2 多个变量指向同一个数组的问题
在实际开发中可能存在一种特殊情况,就是多个变量指向同一个数组对象的形式。
讲解这个知识点的目的,是让同学们注意多个变量指向同一个数组对象存在什么问题?
我们先看一段代码
public class ArrayDemo2 {
public static void main(String[] args) {
// 目标:认识多个变量指向同一个数组对象的形式,并掌握其注意事项。
int[] arr1 = {11, 22, 33};
// 把int类型的数组变量arr1赋值给int类型的数组变量arr2
int[] arr2 = arr1;
System.out.println(arr1); // [I@372f7a8d
System.out.println(arr2); // [I@372f7a8d
arr2[1] = 99;
System.out.println(arr1[1]); // 99
arr2 = null; // 拿到的数组变量中存储的值是null
System.out.println(arr2); // null
System.out.println(arr1); // [I@372f7a8d
//System.out.println(arr2[0]); // Exception in thread "main" java.lang.NullPointerException: Cannot load from int array because "arr2" is null at Main.main(Main.java:20)
//System.out.println(arr2.length);
}
}

刚执行完int[] arr1 = {11,22,33};时,内存原理如下

当执行完int[] arr2 = arr1;后,内存原理如下

当执行到arr2[1]=99;时,内存原理如下

总结一下:
- 两个变量指向同一个数组时,两个变量记录的是同一个地址值。
- 当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。
day05 方法
二、方法的其他形式
设计一个合理的方法的原则如下:
- 如果方法不需要返回数据,返回值类型必须申明成void(无返回值申明), 此时方法内部不可以使用return返回数据。
- 方法如果不需要接收外部传递进来的数据,则不需要定义形参,且调用方法时也不可以传数据给方法。
- 没有参数,且没有返回值类型(void)的方法,称为值无参数、无返回值方法。此时调用方法时不能传递数据给方法。
五、方法在计算机中的执行原理
我们知道Java程序的运行,都是在内存中执行的,而内存区域又分为栈、堆和方法区。那Java的方法是在哪个内存区域中执行呢?
答案是栈内存。 每次调用方法,方法都会进栈执行;执行完后,又会弹栈出去。
假设在main方法中依次调用A方法、B方法、C方法,在内存中的执行流程如下:
- 每次调用方法,方法都会从栈顶压栈执行没执行
- 每个方法执行完后,会从栈顶弹栈出去
5.1 有返回值的方法,内存分析
public class MethodDemo {
public static void main(String[] args) {
int rs = sum(10, 20);
System.out.println(rs);
}
public static int sum(int a, int b ){
int c = a + b;
return c;
}
}

5.2 无返回值的方法,内存分析
public class Demo2Method {
public static void main(String[] args) {
study();
}
public static void study(){
eat();
System.out.println("学习");
sleep();
}
public static void eat(){
System.out.println("吃饭");
}
public static void sleep(){
System.out.println("睡觉");
}
}

1.方法的运行区域在哪里?
答:栈内存。
2.栈有什么特点?方法为什么要在栈中运行自己?
答:先进后出。保证一个方法调用完另一个方法后,可以回来继续执行。
六、方法参数的传递机制
因为我们刚才演示的一些方法中传递的参数都是基本类型,实际上参数还可以是传递引用类型。接下来,学习一下当参数是基本类型时、和参数是引用类型时的区别。
先记住一个结论:Java的参数传递机制都是:值传递
所谓值传递:指的是在传递实参给方法的形参的时候,传递的是实参变量中存储的值的副本。

6.1 参数传递的基本类型数据

6.3 参数传递的是引用数据类型

我们发现调用change方法时参数是引用类型,实际上也是值传递,只不过参数传递存储的地址值。此时change方法和main方法中两个方法中各自有一个变量arrs,这两个变量记录的是同一个地址值[I@4c873330,change方法把数组中的元素改了,main方法在访问时,元素已经被修改了。
1.基本类型和引用类型的参数在传递的时候有什么不同?
= 都是值传递
- 基本类型的参数传递存储的数据值。
- 引用类型的参数传递存储的地址值。
八、方法重载
所谓方法重载指的是:一个类中,出现多个相同的方法名,但是它们的形参列表是不同的,那么这些方法就称为方法重载了。
下面案例中有多个test方法,但是参数列表都不一样,它们都是重载的方法。调用时只需要通过参数来区分即可。
public class MethodOverLoadDemo1 {
public static void main(String[] args) {
// 目标:认识方法重载,并掌握其应用场景。
test();
test(100);
}
public static void test(){
System.out.println("===test1===");
}
public static void test(int a){
System.out.println("===test2===" + a);
}
void test(double a){
}
void test(double a, int b){
}
void test(int b, double a){
}
int test(int a, int b){
return a + b;
}
}
// 不管以什么样的方式发武器,其实最终的目的都是发武器。
// 所以我们可以设计几个名称相同的方法,这样调用者调用起来就不用记那么多名字了
public class MethodTest2 {
public static void main(String[] args) {
// 目标:掌握方法重载的应用场景。
fire();
fire("岛国2");
fire("米国", 999);
}
public static void fire(){
fire("岛国");
}
public static void fire(String country){
fire(country, 1);
}
public static void fire(String country, int number){
System.out.println("发射了" + number + "枚武器给" + country);
}
}
1.什么是方法重载?
答:一个类中,多个方法的名称相同,但它们形参列表不同。
2.方法重载需要注意什么?
- 一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,
其它的都不管(如:修饰符,返回值类型是否一样都无所谓)。
- 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。
3、方法重载有啥应用场景?
答:开发中我们经常需要为处理一类业务,提供多种解决方案,此时用方法重载来设计是很专业的。
day07 面向对象基础
二、深刻认识面向对象
一句话总结,对象其实就是一张数据表,表当中记录什么数据,对象就处理什么数据。
那么这个数据表是怎么来的呢?这张表是不会无缘无故存在的,因为Java也不知道你这个对象要处理哪些数据,所以这张表需要我们设计出来。
用什么来设计这张表呢?就是类(class),类可以理解成对象的设计图,或者对象的模板。
我们需要按照对象的设计图创造一个对象。设计图中规定有哪些数据,对象中就只能有哪些数据。
三、对象在计算机中的执行原理
按照我们之前讲的数组的执行原理,数组变量记录的其实数数组在堆内存中的地址。其实面向对象的代码执行原理和数组的执行原理是非常类似的。
其实Student s1 = new Student();这句话中的原理如下
Student s1表示的是在栈内存中,创建了一个Student类型的变量,变量名为s1- 而
new Student()会在堆内存中创建一个对象,而对象中包含学生的属性名和属性值
同时系统会为这个Student对象分配一个地址值0x4f3f5b24 - 接着把对象的地址赋值给栈内存中的变量s1,通过s1记录的地址就可以找到这个对象
- 当执行
s1.name=“播妞”时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为播妞;

四、类和对象的一些注意事项


五、this关键字
this是什么呢?
this就是一个变量,用在方法中,可以拿到当前类的对象。
我们看下图所示代码,通过代码来体会这句话到底是什么意思。哪一个对象调用方法方法中的this就是哪一个对象

上面代码运行结果如下

this有什么用呢?
通过this在方法中可以访问本类对象的成员变量。我们看下图代码,分析打印结果是多少


六、构造器
什么是构造器?
构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相同。
如下图所示:下面有一个Student类,构造器名称也必须叫Student;也有空参数构造器,也可以有有参数构造器。

构造器的特点?
在创建对象时,会调用构造器。
也就是说 new Student()就是在执行构造器,当构造器执行完了,也就意味着对象创建成功。
当执行new Student("播仔",99)创建对象时,就是在执行有参数构造器,当有参数构造器执行完,就意味着对象创建完毕了。
new 对象就是在执行构造方法

构造器的应用场景?
在创建对象时,可以用构造方法给成员变量赋值。
构造器的注意事项?
学习完构造器的应用场景之后,接下来我们再看一下构造器有哪些注意事项。
1.在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
2.一定定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构造器。
七、封装性
1. 什么是封装呢?
所谓封装,就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理数据的方法,都设计到一个对象中去。
比如:在设计学生类时,把学生对象的姓名、语文成绩、数学成绩三个属性,以及求学生总分、平均分的方法,都封装到学生对象中来。
封装的设计规范用8个字总结,就是:合理隐藏、合理暴露
2.封装在代码中的体现
一般我们在设计一个类时,会将成员变量隐藏,然后把操作成员变量的方法对外暴露。
这里需要用到一个修饰符,叫private,被private修饰的变量或者方法,只能在本类中被访问。
如下图所示,private double score; 就相当于把score变量封装在了Student对象的内部,且不对外暴露,你想要在其他类中访问score这个变量就,就不能直接访问了;
如果你想给Student对象的score属性赋值,得调用对外暴露的方法public void setScore(int score),在这个方法中可以对调用者传递过来的数据进行一些控制,更加安全。当你想获取socre变量的值时,就得调用对外暴露的另一个方法 public int getScore()
八、JavaBean实体类
1. 什么是实体类?
实体类就是一种特殊的类,它需要满足下面的要求:
1)这个类中的成员变量都要私有,并且对外提供相应的getXxx,setXxx方法
2)类中必须要有一个公共的无参的构造器
写完实体类之后,我们看一看它有什么特点? 其实我们会发现实体类中除了有给对象存、取值的方法就没有提供其他方法了。所以实体类仅仅只是用来封装数据用的。
2. 实体类的应用场景
在实际开发中,实体类仅仅只用来封装数据,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。如下图所示

在实际应用中,会将类作为一种数据类型使用。在StudentOperator类中,定义一个Student类型的成员变量student,然后使用构造器给student成员变量赋值。然后在Student的printPass()方法中,使用student调用Student对象的方法,对Student对象的数据进行处理。
十、成员变量和局部变量的区别


day08 Java常用API
二、包
1. 什么是包
因为Java官方提供的类有很多,为了对这些类进行分门别类的管理,别人把写好的类都是放在不同的包里的。包其实类似于文件夹,一个包中可以放多个类文件。
建包的语法格式:
//类文件的第一行定义包 // IDEA会自动加这一行
package com.itheima.javabean;
public class 类名{
}
2. 在自己的程序中,调用其他包中的程序,需要注意下面一个问题
- 如果当前程序中,要调用自己所在包下的其他程序,可以直接调用。(同一个包下的类,互相可以直接调用)
- 如果当前程序中,要调用其他包下的程序,则必须在当前程序中导包, 才可以访问!
导包格式:import 包名.类名 - 如果当前程序中,要调用Java.lang包下的程序,不需要我们导包的,可以直接使用。
- 如果当前程序中,要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问。
三、String类
1. String类概述
String类来代表字符串,这个类就是java.lang包下。
2. String创建对象
String类的API中,有这么一句话:“Java程序中的所有字符串字面值(如"abc")都是字符串的实例实现”。这里所说的实例实现,其实指的就是字符串对象。
意思就是:所有Java的字符串字面值,都是字符串对象。
- 所以创建String对象的第一种方式就有了
String s1 = "abc"; //这里"abc"就是一个字符串对象,用s1变量接收
String s2 = "黑马程序员"; //这里的“黑马程序员”也是一个字符串对象,用s2变量接收
- 创建String对象还有第二种方式,就是利用String类的构造方法创建String类的对象。

我们前面学习过类的构造方法,执行构造方法需要用到new关键字。new String(参数)就是在执行String类的构造方法。
下面我们演示通过String类的构造方法,创建String类的对象
// 1、直接双引号得到字符串对象,封装字符串数据
String name = "黑马666";
System.out.println(name); // 黑马666
// 2、new String创建字符串对象,并调用构造器初始化字符串
String rs1 = new String();
System.out.println(rs1); // ""
String rs2 = new String("itheima");
System.out.println(rs2); // itheima
char[] chars = {'a', '黑', '马'};
String rs3 = new String(chars);
System.out.println(rs3); // a黑马
byte[] bytes = {97, 98, 99};
String rs4 = new String(bytes);
System.out.println(rs4); // abc
3. String类的常用方法
public class StringDemo2 {
public static void main(String[] args) {
//目标:快速熟悉String提供的处理字符串的常用方法。
String s = "黑马Java";
// 1、获取字符串的长度
System.out.println(s.length());
// 2、提取字符串中某个索引位置处的字符
char c = s.charAt(1);
System.out.println(c);
// 字符串的遍历
for (int i = 0; i < s.length(); i++) {
// i = 0 1 2 3 4 5
char ch = s.charAt(i);
System.out.println(ch);
}
System.out.println("-------------------");
// 3、把字符串转换成字符数组,再进行遍历
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
// 4、判断字符串内容,内容一样就返回true
String s1 = new String("黑马");
String s2 = new String("黑马");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
// 5、忽略大小写比较字符串内容
String c1 = "34AeFG";
String c2 = "34aEfg";
System.out.println(c1.equals(c2)); // false
System.out.println(c1.equalsIgnoreCase(c2)); // true
// 6、截取字符串内容 (包前不包后的)
String s3 = "Java是最好的编程语言之一";
String rs = s3.substring(0, 8);
System.out.println(rs);
// 7、从当前索引位置一直截取到字符串的末尾
String rs2 = s3.substring(5);
System.out.println(rs2);
// 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们
String info = "这个电影简直是个垃圾,垃圾电影!!";
String rs3 = info.replace("垃圾", "**");
System.out.println(rs3);
// 9、判断字符串中是否包含某个关键字
String info2 = "Java是最好的编程语言之一,我爱Java,Java不爱我!";
System.out.println(info2.contains("Java"));
System.out.println(info2.contains("java"));
System.out.println(info2.contains("Java2"));
// 10、判断字符串是否以某个字符串开头。
String rs4 = "张三丰";
System.out.println(rs4.startsWith("张"));
System.out.println(rs4.startsWith("张三"));
System.out.println(rs4.startsWith("张三2"));
// 11、把字符串按照某个指定内容分割成多个字符串,放到一个字符串数组中返回给我们
String rs5 = "张无忌,周芷若,殷素素,赵敏";
String[] names = rs5.split(",");
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
}
}
4. String的注意事项
注意事项1:String类的对象是不可变的对象
String对象的内容不可改变,被称为不可变字符串对象。

以上代码中,先定义了一个String变量 name第一次赋值为“黑马”; 然后对name变量记录的字符串进行两次拼接,第一次拼接“程序员”,第二次拼接“播妞”;我们发现得到的结果是:黑马程序员播妞
这里问题就来了,你不是是说:**String类的对象是不可变的字符串对象吗?**我看name的值变了呀!!!
下面我们就解释一下,String是不可变对象到底是什么含义。
需要注意的是:只要是以“”方式写出的字符串对象,会在堆内存中的字符串常量池中存储。
执行第一句话时,会在堆内存的常量池中,创建一个字符串对象“黑马”,然后把“黑马”的地址赋值给String name

当执行第二句话时,又会再堆内存的常量池中创建一个字符串“程序员”,和“黑马”拼接,拼接之后还会产生一个新的字符串对象”黑马程序员“,然后将新产生的“黑马程序员”对象的地址赋值给String name变量。

此时你会发现,之前创建的字符串对象“黑马”内容确实是没有改变的。所以说String的对象是不可变的。
注意事项2:字符串字面量和new出来字符串的区别
- 只要是以
“...”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。如下图一所示 - 但通过
new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。如下图二所示


5. String案例一:用户登录案例
public class StringTest4 {
public static void main(String[] args) {
// 1、开发一个登录界面
for (int i = 0; i < 3; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("请您输入登录名称:");
String loginName = sc.next();
System.out.println("请您输入登录密码:");
String passWord = sc.next();
// 5、开始调用登录方法,判断是否登录成功
boolean rs = login(loginName, passWord);
if(rs){
System.out.println("恭喜您,欢迎进入系统~~");
break; // 跳出for循环,代表登录完成
}else {
System.out.println("登录名或者密码错误,请您确认~~");
}
}
}
/**
2、开发一个登录方法,接收用户的登录名和密码,返回认证的结果
*/
public static boolean login(String loginName, String passWord){
// 3、准备一份系统正确的登录名和密码
String okLoginName = "itheima";
String okPassWord = "123456";
// 4、开始正式判断用户是否登录成功
/*if(okLoginName.equals(loginName) && okPassWord.equals(passWord)){
// 登录成功的
return true;
}else {
return false;
}*/
return okLoginName.equals(loginName) && okPassWord.equals(passWord);
}
}
四、ArrayList类
1. ArrayList快速入门
ArrayList表示一种集合,它是一个容器,用来装数据的,类似于数组。那有了数组,为什么要有集合呢?
因为数组一旦创建大小不变,比如创建一个长度为3的数组,就只能存储3个元素,想要存储第4个元素就不行。而集合是大小可变的,想要存储几个元素就存储几个元素,在实际工作中用得更多。
然后集合有很多种,而ArrayList只是众多集合中的一种,跟多的集合我们在就业班的课程中再学习。如下图所示:

集合该怎么学呢?1. 首先你要会创建集合对象,2. 然后能够调用集合提供的方法对容器中的数据进行增删改查,3. 最后知道集合的一些特点就可以了。
2. ArrayList常用方法
想要使用ArrayList存储数据,并对数据进行操作:
- 第一步:创建ArrayList容器对象。一般使用空参数构造方法,如下图所示:
- 第二步:调用ArrayList类的常用方法对容器中的数据进行操作。常用方法如下:

public class ArrayListDemo1 {
public static void main(String[] args) {
// 1、创建一个ArrayList的集合对象
// ArrayList<String> list = new ArrayList<String>();
// 从jdk 1.7开始才支持的
ArrayList<String> list = new ArrayList<>();
list.add("黑马");
list.add("黑马");
list.add("Java");
System.out.println(list); // [黑马, 黑马, Java]
// 2、往集合中的某个索引位置处添加一个数据
list.add(1, "MySQL");
System.out.println(list); // [黑马, MySQL, 黑马, Java]
// 3、根据索引获取集合中某个索引位置处的值
String rs = list.get(1);
System.out.println(rs); // MySQL
// 4、获取集合的大小(返回集合中存储的元素个数)
System.out.println(list.size()); // 4
// 5、根据索引删除集合中的某个元素值,会返回被删除的元素值给我们
System.out.println(list.remove(1)); // MySQL
System.out.println(list); // [黑马, 黑马, Java]
// 6、直接删除某个元素值,删除成功会返回true,反之
System.out.println(list.remove("Java")); // true
System.out.println(list); // [黑马, 黑马]
list.add(1, "html");
System.out.println(list); // [黑马, html, 黑马]
// 默认删除的是第一次出现的这个黑马的数据的
System.out.println(list.remove("黑马")); // true
System.out.println(list); // [html, 黑马]
// 7、修改某个索引位置处的数据,修改后会返回原来的值给我们
System.out.println(list.set(1, "黑马程序员")); // 黑马
System.out.println(list); // [html, 黑马程序员]
}
}
3. ArrayList应用案例1
掌握从容器中找出某些数据并成功删除的技巧
错误示范:
public class ArrayListTest2 {
public static void main(String[] args) {
// 1、创建一个ArrayList集合对象
ArrayList<String> list = new ArrayList<>();
list.add("枸杞");
list.add("Java入门");
list.add("宁夏枸杞");
list.add("黑枸杞");
list.add("人字拖");
list.add("特级枸杞");
list.add("枸杞子");
System.out.println(list);
//运行结果如下: [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]
// 2、开始完成需求:从集合中找出包含枸杞的数据并删除它
for (int i = 0; i < list.size(); i++) {
// i = 0 1 2 3 4 5
// 取出当前遍历到的数据
String ele = list.get(i);
// 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele);
}
}
System.out.println(list);
//删除后结果如下:[Java入门, 黑枸杞, 人字拖, 枸杞子]
}
}
(运行完上面代码,我们会发现,删除后的集合中,竟然还有黑枸杞,枸杞子在集合中。)
那如何解决这个问题呢?这里打算给大家提供两种解决方案:
- 集合删除元素方式一:每次删除完元素后,让控制循环的变量
i--就可以了;如下图所示

// 方式一:每次删除一个数据后,就让i往左边退一步
for (int i = 0; i < list.size(); i++) {
// i = 0 1 2 3 4 5
// 取出当前遍历到的数据
String ele = list.get(i);
// 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele);
i--;
}
}
System.out.println(list);
- 集合删除元素方式二:我们只需要倒着遍历集合,在遍历过程中删除元素就可以了


// 方式二:从集合的后面倒着遍历并删除
// [Java入门, 人字拖]
// i
for (int i = list.size() - 1; i >= 0; i--) {
// 取出当前遍历到的数据
String ele = list.get(i);
// 判断这个数据中包含枸杞
if(ele.contains("枸杞")){
// 直接从集合中删除该数据
list.remove(ele);
}
}
System.out.println(list);
4. ArrayList应用案例2
ArrayList的综合案例-模仿外卖系统中的商家系统
需求
●完成菜品的上架、以及菜品信息浏览功能。
目标
●使用所学的ArrayList集合结合面向对象编程实现以上2个需求。
首先我们先定义一个菜品类(Food类),用来描述每一个菜品对象要封装那些数据。
public class Food {
private String name; //菜品名称
private double originalPrice; //菜品原价
private double specialPrice; //菜品优惠价
private String info; //菜品其他信息
public Food() {
}
public Food(String name, double originalPrice, double specialPrice, String info) {
this.name = name;
this.originalPrice = originalPrice;
this.specialPrice = specialPrice;
this.info = info;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getOriginalPrice() {
return originalPrice;
}
public void setOriginalPrice(double originalPrice) {
this.originalPrice = originalPrice;
}
public double getSpecialPrice() {
return specialPrice;
}
public void setSpecialPrice(double specialPrice) {
this.specialPrice = specialPrice;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
接下来写一个菜品管理类,提供上架菜品的功能、浏览菜品的功能、展示操作界面的功能。
public class FoodManager{
//为了存储多个菜品,预先创建一个ArrayList集合;
//上架菜品时,其实就是往集合中添加菜品对象
//浏览菜品时,其实就是遍历集合中的菜品对象,并打印菜品对象的属性信息。
private ArrayList<Food> foods = new ArrayList<>();
//为了在下面的多个方法中,能够使用键盘录入,提前把Scanner对象创建好;
private Scanner sc = new Scanner(System.in);
/**
1、商家上架菜品
*/
public void add(){
System.out.println("===菜品上架==");
// 2、提前创建一个菜品对象,用于封装用户上架的菜品信息
Food food = new Food();
System.out.println("请您输入上架菜品的名称:");
String name = sc.next();
food.setName(name);
System.out.println("请您输入上架菜品的原价:");
double originalPrice = sc.nextDouble();
food.setOriginalPrice(originalPrice);
System.out.println("请您输入上架菜品的优惠价:");
double specialPrice = sc.nextDouble();
food.setSpecialPrice(specialPrice);
System.out.println("请您输入上架菜品的其他信息:");
String info = sc.next();
food.setInfo(info);
// 3、把菜品对象添加到集合容器中去
foods.add(food);
System.out.println("恭喜您,上架成功~~~");
}
/**
2、菜品;浏览功能
*/
public void printAllFoods(){
System.out.println("==当前菜品信息如下:==");
for (int i = 0; i < foods.size(); i++) {
Food food = foods.get(i);
System.out.println("菜品名称:" + food.getName());
System.out.println("菜品原价:" + food.getOriginalPrice());
System.out.println("菜品优惠价:" + food.getSpecialPrice());
System.out.println("其他描述信息:" + food.getInfo());
System.out.println("------------------------");
}
}
/**
3、专门负责展示系统界面的
*/
public void start(){
while (true) {
System.out.println("====欢迎进入商家后台管理系统=====");
System.out.println("1、上架菜品(add)");
System.out.println("2、浏览菜品(query)");
System.out.println("3、退出系统(exit)");
System.out.println("请您选择操作命令:");
String command = sc.next();
switch (command) {
case "add":
add();
break;
case "query":
printAllFoods();
break;
case "exit":
return; // 结束当前方法!
default:
System.out.println("您输入的操作命令有误~~");
}
}
}
}
最后在写一个测试类Test,在测试类中进行测试。其实测试类,只起到一个启动程序的作用。
public class Test {
public static void main(String[] args) {
FoodManager manager = new FoodManager();
manager.start();
}
}
1219

被折叠的 条评论
为什么被折叠?



