零基础JAVA——黑马程序员课程笔记
视频地址:点击访问
(我这里开发工具有时候用eclipse有时候用IDEA,看每个人的习惯)
(文中代码部分不会和老师讲的一模一样,因为我都是在看到老师给的案例后自己尝试写的,推荐大家这样做,可以帮助大家掌握)
文章目录
- JAVA语言发展史
- JAVA跨平台原理
- JRE和JDK
- JRE (Java Runtime Environment)
- JDK (Java Development Kit)
- JDK安装目录
- 为什么要配置Path环境变量
- Java程序开发运行流程
- dos命令
- 数据类型
- 变量使用的注意事项:
- 标识符定义规则
- 常见命名约定
- 类型转换
- 自动类型转换
- 强制类型转换
- 运算符
- 算术运算符
- 字符的+操作
- 字符串的+操作
- 赋值运算符
- 自增自减运算符
- 关系运算符
- 逻辑运算符
- 短路逻辑运算符
- 三元运算符
- 数据输入
- Scanner使用的基本步骤
- 流程控制
- 分支结构
- if语句
- switch语句
- 循环结构
- for语句
- 经典案例:
- while语句
- 三种循环的区别
- Random作用和使用步骤
- 猜数字案例
- 数组
- 数组定义格式
- 什么是数组
- 数组定义格式
- 数组初始化之动态初始化
- 数组初始化概述
- 数组初始化方式
- 动态初始化
- 数组元素访问
- 内存分配
- Java中内存分配
- 数组初始化之静态初始化
- 数组操作的两个常见小问题
- 数组常见操作
- 遍历
- 获取最值
- 方法
- 方法概述
- 什么是方法
- 方法的定义和调用
- 方法定义
- 方法调用
- 带返回值方法的定义和调用
- 带返回值方法定义
- 方法的注意事项
- 方法注意事项
- 方法的通用格式
- 方法重载
- 方法的参数传递
- 方法参数传递(基本类型)
- 方法参数传递(引用类型)
- 案例
- Debug(IDEA演示)
- Debug操作流程
- Debug使用
- 阶段综合案例(这里我只做了部分)
- 减肥问题(会穿插==和equal()使用的知识)
- 不死神兔
- 百钱百鸡
- 数组内容相同
- 反转
- 面向对象基础
- 类和对象
- 什么是对象
- 什么是类
- 什么是对象的属性
- 什么是对象的行为
- 类和对象的关系
- 类的定义
- 对象的使用
- 案例
- 对象内存图
- 对象内存图(单个对象)
- 对象内存图(多个对象)
- 对象内存图(多个对象指向相同)
- 成员变量和局部变量
- 成员变量与局部变量的区别
- 封装
- private关键字
- private关键字的使用
- this关键字
- 封装
- 构造方法
- 构造方法注意事项
- 标准类的制作
- 字符串
- API
- API概述
- String
- String概述
- String构造方法
- String对象特点
- 字符串比较
- 案例
- 用户登录
- 遍历字符串
- 统计字符次数
- 拼接字符串
- StringBuilder
- StringBuilder概述
- StringBuilder构造方法
- StringBuilder的添加和反转方法
- StringBuilder 和String相互转换
- 案例
- 拼接字符串
- 字符串反转
- 集合基础
- 集合概述
- ArrayList构造方法和添加方法
- ArrayList常用方法
- 案例
- 存储字符串并遍历
- 存储学生对象并遍历
- 改进后
- 学生管理系统
- 继承
- 继承概述
- 继承的好处和弊端
- 继承中变量的访问特点
- super
JAVA语言发展史
JAVA跨平台原理
JRE和JDK
JRE (Java Runtime Environment)
是Java程序的运行时环境,包含JVM和运行时所需要的核心类库。
我们想要运行一个已有的Java程序, 那么只需安装JRE即可。
JDK (Java Development Kit)
是Java程序开发工具包,包含JRE和开发人员使用的工具。
其中的开发工具:编译工具(javac.exe)和运行工具(java.exe) 。
我们想要开发一个全新的Java程序,那么必须安装JDK。
JDK安装目录
为什么要配置Path环境变量
开发Java程序,需要使用JDK提供的开发工具,而这些工具在JDK的安装目录的bin目录下。
为了在开发Java程序的时候,能够方便的使用javac和java这些命令,我们需要配置Path环境变量。
Java程序开发运行流程
开发Java程序,需要三个步骤:编写程序,编译程序,运行程序
空常量不能直接输出
dos命令
数据类型
变量使用的注意事项:
名字不能重复
变量未赋值,不能使用
long类型的变量定义的时候,为了防止整数过大,后面要加L
float类型的变量定义的时候,为了防止类型不兼容,后面要加F
标识符定义规则
●由数字、字母、下划线( )和美元符($)组成
●不能以数字开头
●不能是关键字
●区分大小写
常见命名约定
小驼峰命名法:方法、变量
●约定1:标识符是一个单词的时候,首字母小写
●范例1:name
●约定2: 标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写
●范例2: firstName
大驼峰命名法:类
●约定1: 标识符是一个单词的时候,首字母大写
●范例1: Student
●约定2: 标识符由多个单词组成的时候,每个单词的首字母大写
●范例2: GoodStudent
类型转换
自动类型转换
把一个表示数据范围小的数值或者变量赋值给另-个表示数据范围大的变量
范例: doubled = 10;
强制类型转换
把一个表示数据范围大的数值或者变量赋值给另-个表示数据范围小的变量
●格式:目标数据类型变量名= (目标数据类型)值或者变量;
●范例: intk = (int)88.88;
运算符
算术运算符
字符的+操作
package test;public class test {public static void main(String[] args) {int i = 0;char c = 'A';//'A'的值是65System.out.println(i + c);}
}
结果:
提升规则:
- byte类型, short类型和char类型将被提升到int类型
- 整个表达式的类型自动提升到表达式中最等级操作数同样的类型
- 等级顺序: bvte. short.char->int-> lona-> float > double
字符串的+操作
package test;public class test {public static void main(String[] args) {System.out.println("hello"+"earth");System.out.println("hello"+ 6666);System.out.println(6666+ "hello");System.out.println("hello"+6+666);System.out.println(6+666+"hello");}
}
结果:
赋值运算符
红色的运算符隐含着强制类型转换
自增自减运算符
单独使用
package test;public class test {public static void main(String[] args) { //单独使用int i = 1;System.out.println("i="+i);i++;System.out.println("i="+i);++i;System.out.println("i="+i);}
}
结果:
参与操作使用
package test;public class test {public static void main(String[] args) { int i = 1;System.out.println("i="+i);//参与操作使用int j = i++;System.out.println("i="+i);System.out.println("j="+j); }
}
结果:
package test;public class test {public static void main(String[] args) { int i = 1;System.out.println("i="+i);//参与操作使用int j = ++i;System.out.println("i="+i);System.out.println("j="+j); }
}
结果:
- 参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者–参与操作的时候,如果放在变量的前边,先拿变量做++或者–,后拿变量参与操作。
关系运算符
逻辑运算符
短路逻辑运算符
区别:
注意事项:
逻辑与&,无论左边真假,右边都要执行。
短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。
逻辑或|,无论左边真假,右边都要执行。
短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
三元运算符
计算规则:
首先计算关系表达式的值
如果值为true,表达式1的值就是运算结果如果值为false,表达式2的值就是运算结果
数据输入
Scanner使用的基本步骤
package test;import java.util.Scanner;public class test {public static void main(String[] args) { Scanner sc = new Scanner(System.in);int i = sc.nextInt();System.out.println("i="+i);sc.close();//关闭sc接口}
}
结果:
流程控制
分支结构
if语句
public class test {public static void main(String[] args) { Scanner sc = new Scanner(System.in);int a = sc.nextInt();if (a % 2 == 0)System.out.println("a是偶数");elseSystem.out.println("a是奇数");sc.close();}
}
结果:
switch语句
输入一个数字判断是什么季节
public class test {public static void main(String[] args) { Scanner sc = new Scanner(System.in);int i = sc.nextInt();switch (i) {case 1:System.out.println("春季");break;case 2:System.out.println("春季");break;case 3:System.out.println("春季");break;case 4:System.out.println("夏季");break;case 5:System.out.println("夏季");break;case 6:System.out.println("夏季");break;case 7:System.out.println("秋季");break;case 8:System.out.println("秋季");break;case 9:System.out.println("秋季");break;case 10:System.out.println("冬季");break;case 11:System.out.println("冬季");break;case 12:System.out.println("冬季");break;default:System.out.println("输入不合法");break;}sc.close();}
}
利用case穿透性
//case穿透
public class test {public static void main(String[] args) { Scanner sc = new Scanner(System.in);int i = sc.nextInt();switch (i) {case 1:case 2:case 3:System.out.println("春季");break;case 4:case 5:case 6:System.out.println("夏季");break; case 7:case 8:case 9:System.out.println("秋季");break; case 10:case 11:case 12:System.out.println("冬季");break; default:System.out.println("输入不合法");}sc.close();}
}
循环结构
for语句
经典案例:
public class test {public static void main(String[] args) {
//先找到100——999for(int i = 100;i < 1000;i++) {//判断条件int a = i % 10;int b = i / 10 % 10;int c = i / 100 % 10;if(a*a*a+b*b*b+c*c*c == i) {System.out.println(i);}}}
}
结果:
while语句
public class test {public static void main(String[] args) {int i = 0;double hou = 0.1;while(hou <=8844430) {i++;hou = hou*2;}System.out.println(i);}
}
结果:
三种循环的区别
Random作用和使用步骤
作用:产生一个随机数
猜数字案例
package test;
import java.util.Random;
import java.util.*;public class test1 {public static void main(String []args ) {Random r = new Random();int num = r.nextInt(100)+1;System.out.println(num);Scanner sc = new Scanner(System.in);while(true) {int num1 = sc.nextInt();if(num > num1) {System.out.println("需要猜大一点");}else if(num < num1) {System.out.println("需要猜小一点");}else {System.out.println("猜对了,你真厉害");break;}}}
}
结果:
数组
数组定义格式
什么是数组
数组(array)是一种用于存储多个相同类型数据的存储模型
数组定义格式
数组初始化之动态初始化
数组初始化概述
Java中的数组必须先初始化然后才能使用
所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
数组初始化方式
动态初始化和静态初始化
动态初始化
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值。
- int:说明数组中元素的类型是int
- [ ]:说明这是一个数组
- arr:这是数组的名称
- new:为数组申请内存空间
- int:说明数组中元素的类型是int
- [ ]:说明这是一个数组
- 3:数组长度,其实就是数组中的元素个数
数组元素访问
public class test1 {public static void main(String []args ) {int[] arr = new int [5];//输出数组名System.out.println(arr);//输出数组元素System.out.println(arr[0]);}
}
结果:
内存分配
Java中内存分配
Java程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
***这里arr指向的是内存地址,这个内存地址是首地址(数组首地址)***
数组初始化之静态初始化
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度
public class test1 {public static void main(String []args ) {int[] arr = {1,2,3};int[] arr1 = {3,2,1};System.out.println(arr);System.out.println(arr[0]);System.out.println(arr1);System.out.println(arr1[0]);}
}
结果:
数组操作的两个常见小问题
public class test1 {public static void main(String []args ) {int[] arr = new int[3];System.out.println(arr);System.out.println(arr[0]);arr = null;System.out.println(arr);System.out.println(arr[0]);}
}
结果:
发生空指针异常,当arr = null时,指针不再有指向。
数组常见操作
遍历
public class test1 {public static void main(String []args ) {int[] arr = {1,2,3,4,5,6};for(int i = 0;i < arr.length;i++) {System.out.println(arr[i]);}}
}
结果:
获取最值
public class test1 {public static void main(String []args ) {//获取最值//定义一个数组int[] arr = {3,1,2,4};//定义存放最大值,令他等于数组第一个元素int max = arr [0];//循环比较找出真正的最大值for(int i = 1;i < arr.length;i++) {if(max <= arr[i]) {max = arr[i];}}System.out.println(max);}
}
结果:
方法
方法概述
什么是方法
方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集
注意:
- 方法必须先创建才可以使用,该过程称为方法定义
- 方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
方法的定义和调用
方法定义
方法调用
- 判断输入的数字是否是偶数(在视频讲解的基础上自己稍稍调整的代码)
public class test1 {public static void main(String []args ) {Scanner sc = new Scanner(System.in);int a = sc.nextInt();//函数调用isnumber(a);sc.close();}
//定义判断是否是偶数的方法
public static void isnumber(int i) {if(i % 2 == 0) {System.out.println("是偶数");}else {System.out.println("不是偶数");}}
}
结果:
- 判断数组中的最大元素(在视频讲解的基础上自己稍稍调整的代码)
public class test1 {public static void main(String []args ) {int[] arr = {1,5,2,3,7};getmax(arr);}//获取数组中最大数public static void getmax(int i[]) {int max = i[0];for(int a = 1;a < i.length;a++) {if(max <= i[a]) {max = i[a];}}System.out.println(max);}
}
结果:
带返回值方法的定义和调用
带返回值方法定义
- 方法定义时return后面的返回值与方法定义上的数据类型要匹配,否则程序将报错
- 方法的返回值通常会使用变量接收,否则该返回值将无意义
方法的注意事项
方法注意事项
- 方法不能嵌套定义
- void表示无返回值,可以省略return,也可以单独的书写return,后面不加数据
方法的通用格式
定义方法时,要做到两个明确
- 明确返回值类型:主要是明确方法操作完毕之后是否有数据返回,如果没有,写void;如果有,写对应的数据类型明确参数:主要是明确参数的类型和数量
- 调用方法时
void类型的方法,直接调用即可
非void类型的方法,推荐用变量接收调用
方法重载
方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载
- 多个方法在同一个类中
- 多个方法具有相同的方法名
- 多个方法的参数不相同,类型不同或者数量不同
###重载实例
需求:使用方法重载的思想,设计比较两个整数是否相同的方法,兼容全整数类型(byte,short,intlong)
public class test1 {public static void main(String []args ) {boolean a = compare(1,2);System.out.println(a);boolean c = compare((byte)1,(byte)2);//类型转换System.out.println(c);boolean b = compare(2.0,2.0);System.out.println(b);}//定义比较两个数字是否相同public static boolean compare(int a,int b) {System.out.println("int");return(a == b);}public static boolean compare(double a,double b) {System.out.println("double");return(a == b);}public static boolean compare(byte a,byte b) {System.out.println("byte");return(a == b);}
}
结果:
方法的参数传递
了解形参与实参可以参考其它作者文章:点击查看
基本类型和引用类型的区别:基本数据类型在声明时系统就给它分配空间;而引用数据类型不同,它声明时只给变量分配了引用空间,而不分配数据空间。
通常 基本类型 和 String 传递是值传递,形参的改变不会影响实参的改变
方法参数传递(基本类型)
对于基本数据类型的参数。形式参数的改变,不影响实际参数的值
结果:
理解
在调用change方法的时候,知识将main方法中的值传给对应的形式参数,函数接收的是原始值的一个拷贝, 此时内存中存在两个相等的基本类型,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。
方法参数传递(引用类型)
对于引用类型的参数,形式参数的改变,影响实际参数的值
结果:
理解
在调用change方法的时候,形参和实参都指向相同的内存地址,所以对形参的修改就是对所指向地址空间数据的修改,此时实参也会发生改变
案例
public class test1 {public static void main(String []args ) {int[] arr = {1,2,4,5,3,6,9};show(arr);}public static void show(int[] a) {System.out.print("[");for(int i = 0;i < a.length;i++) {if(i == a.length-1) {System.out.print(a[i]);}else {System.out.print(a[i]+",");}}System.out.print("]");}
}
结果:
Debug(IDEA演示)
Debug操作流程
Debug调试,又被称为断点调试,断点其实是一个标记,告诉我们从哪里开始查看
- 如何加断点
点击你想要添加断点的代码的前方
- 如何运行加了断点的程序
点击右键,选择debug
- 看哪里
- 点哪里
点击执行,观察窗口的变化
- 如何删除断点
Debug使用
这一部分难度不大,建议自己看视频操作一下,很容易掌握
阶段综合案例(这里我只做了部分)
减肥问题(会穿插==和equal()使用的知识)
这里我想在视频的基础上实现输入的不是数字,而是”星期一“这样的字符串,但在进行字符串比较时出现了问题,如下图:
当我在控制台输入”星期一“后,显示如下图:
并没有像我想的一样成功打印出”跑步“,之后我进行debug发现,没有进行进入循环,说明不符合判断条件,但在我理解中应该是符合判断条件的,这时我把判断条件单独拿出来运行:
当我在控制台输入”星期一“时,输出false
看来不符合判断条件,这里使用连等号不能达到我们的目的
经过搜索资料我发现: 连等号在比较基本数据类型时比较的是值即以下类型比较时是比较的值。具体深入理解java中==和equals的用法可以查看其它作者的文章:点击查看
修改后:
最终可以达到目的,这里只做部分的代码呈现,大家可以自己完整做一下,亲手做才会有收获哦,发现问题解决问题。
不死神兔
public class test {public static void main(String[] args) {int[] arr = new int[20];arr[0] = 1;arr[1] = 1;for (int i = 2;i < arr.length;i++){arr[i] = arr[i-2] + arr[i-1];}System.out.println(arr[19]);}
}
结果:
百钱百鸡
这里我没有采用视频中奖的方法,视频中的方法可以去具体看一下老师讲的(第93个问题)
这里我没有对三种鸡的数量进行分析,只是令所有的数量都小于100,if后用来写约束条件
结果:
但是这里我遗忘了一个条件,小鸡仔的数量卖的时候必须是三个三个卖的,因此小鸡仔的数量必须是3的倍数
由此我做出改进
结果:
数组内容相同
public class test {public static void main(String[] args) {//定义两个数组int[] arr = {1,2,3,4};int[] arr1 = {1,2,3,4};System.out.println(compare(arr,arr1));}public static boolean compare(int[] a,int[] b){//当长度不同时不需要一一比较就可以判断if (a.length != b.length){return false;}for(int i = 0;i < a.length;i++){if (a[i] != b[i]){return false;}}return true;}
}
结果:
反转
public class test {public static void main(String[] args) {//1:定义一个数组,用静态初始化完成数组元素的初始化int[] arr = {1,2,3,4};//2:循环遍历数组,这一次初始化语句定义两个索引变量,判断条件是开始索引小于等于结束索引for (int start=0,end = arr.length-1;start<=end;start++,end--){//3:变量交换int temp = arr[start];arr[start] = arr[end];arr[end] = temp;}show(arr);}//4:遍历数组public static void show(int[] a) {System.out.print("[");for(int i = 0;i < a.length;i++) {if(i == a.length-1) {System.out.print(a[i]);}else {System.out.print(a[i]+",");}}System.out.print("]");}
}
结果:
面向对象基础
类和对象
什么是对象
万物皆对象,客观存在的事物皆为对象
什么是类
类是对现实生活中一类具有共同属性和行为的事物的抽象
(类在现实中不存在)
类的特点:
- 类是对象的数据类型
- 类是具有相同属性和行为的一组对象的集合
什么是对象的属性
属性:对象具有的各种特征,每个对象的每个属性都拥有特定的值
什么是对象的行为
行为:对象能够执行的操作
类和对象的关系
类:类是对现实生活中一类具有共同属性和行为的事物的抽象
对象:是能够看得到摸的着的真实存在的实体
类的定义
- 类的重要性:是Java程序的基本组成单位
- 类是什么:是对现实生活中一类具有共同属性和行为的事物的抽象,确定对象将会拥有的属性和行为
- 类的组成:属性和行为
属性:在类中通过成员变量来体现(类中方法外的变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
对象的使用
package com.java;public class PhoneDemo {public static void main(String[] args){//创建对象Phone p = new Phone();//使用成员变量System.out.println(p.brand);System.out.println(p.price);p.brand = "华为";p.price = 2999;System.out.println(p.brand);System.out.println(p.price);//使用成员方法p.call();p.sendMessage();}}
结果:
案例
结果:
对象内存图
查看堆和栈的相关信息可以看其它作者的文章:点击查看
对象内存图(单个对象)
对象内存图(多个对象)
对象内存图(多个对象指向相同)
成员变量和局部变量
成员变量与局部变量的区别
封装
private关键字
- 是一个权限修饰符
- 可以修饰成员(成员变量和成员方法)
- 作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问
- 针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
- 提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰
private关键字的使用
结果:
this关键字
什么时候使用this呢? 解决局部变量隐藏成员变量
Student类写作这样
在运行测试类后结果是:
因为在setAge方法中指代不清楚,导致认为age都是局部变量。进行如下修改
用this来指代成员变量就会避免冲突,达到预想的效果。结果:
封装
1.封装概述
是面向对象三大特征之一(封装,继承,多态)
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
2.封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxox()/setXxx()方法
3.封装好处
通过方法来控制成员变量的操作,提高了代码的安全性把代码用方法进行封装,提高了代码的复用性
构造方法
结果:
构造方法注意事项
可能大家会疑问,为什么之前没有给出构造方法,仍然可以这样使用上述语句:那是因为在没有给出构造方法的时候,系统默认给出无参构造方法。
- 构造方法的创建
如果没有定义构造方法,系统将给出一个默认的无参数构造方法如果定义了构造方法,系统将不再提供默认的构造方法 - 构造方法的重载
如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法 - 推荐的使用方式
无论是否使用,都手工书写无参数构造方法
结果:
标准类的制作
做好下边实例可以带大家充分了解构造方法:
类
public class Student {//成员变量private String name;private int age;//构造方法public Student(){System.out.println("无参构造方法");}public Student(String name,int age){this.age = age;this.name = name;}//set/get方法public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}//成员方法public void show(){System.out.println(name+age);}
}
测试类
public class StudentTest {public static void main(String[] args){//无参构造方法,再使用setXX赋值Student a = new Student();a.setName("小怪兽");a.setAge(12);a.show();System.out.println("____________");//带参构造方法直接创建有属性的对象Student b = new Student("奥特曼",100);b.show();}
}
结果:
字符串
API
API概述
帮助文档的使用可以查看我最上边给出的视频中的讲解,个人比较喜欢直接百度搜索。
注意:
调用方法的时候,如果方法有明确的返回值,我们用变量接收可以手动完成,也可以使用快捷键的方式完成(Ctrl+Alt+V)
String
String概述
String构造方法
public class test {public static void main(String[] args){//String构造方法://public string( ):创建一个空白字符串对象,不含有任何内容String a = new String();System.out.println("a:"+a);//public String(char[] chs):根据字符数组的内容,来创建字符串对象char[] arr = {'a','b','c'};String b = new String(arr);System.out.println("b:"+b);//public String(byte[] bys):根据字节数组的内容,来创建字符串对象byte[] arr1 = {99,98,97};String c = new String(arr1);System.out.println("c:"+c);// 没有使用构造方法,String s =“abc”;直接赋值的方式创建字符串对象,内容就是abcString d = "coco";System.out.println("d:"+d);}
}
结果:
但是推荐使用直接赋值方式
String对象特点
- 通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
上面的代码中,JVM会首先创建一个字符数组,然后每一次new的时候都会有一个新的地址,只不过s1和s2参考的字符串内容是相同的
- 以"”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String 对象,并在字符串池中维护
在上面的代码中,针对第一行代码,JVM会建立一个String对象放在字符串池中,并给s3参考;第二行则让s4直接参考字符串池中的String对象,也就是说它们本质上是同一个对象
字符串比较
想看具体==和equal()的用法可以参考我前边给到的讲解:点击跳转
public class test {public static void main(String[] args){char[] arr = {'a','b','c'};String s1 = new String(arr);String s2 = new String(arr);String s3 = "abc";String s4 = "abc";System.out.println(s1==s2);System.out.println(s1==s3);System.out.println(s3==s4);System.out.println("````````````````````````");System.out.println(s1.equals(s2));System.out.println(s1.equals(s3));System.out.println(s3.equals(s4));}
}
结果:
案例
用户登录
我的代码和课程上的有一点点出入,可以都尝试一下
public class test {public static void main(String[] args){//预先给出用户名和密码String name = "小怪兽";String code = "123abc";for(int i = 1;i <= 3;i++){Scanner sc = new Scanner(System.in);System.out.println("输入用户名:");String name1 = sc.nextLine();System.out.println("输入密码:");String code1 = sc.nextLine();if (name.equals(name1)&&code.equals(code1)){System.out.println("成功登录!欢迎"+name);break;}else if (name.equals(name1)){System.out.println("密码输入错误");}else if (code.equals(code1)){System.out.println("用户名输入错误");}else{System.out.println("用户名和密码输入错误");}}}
}
结果:
遍历字符串
import java.util.Scanner;public class test1 {public static void main(String[] args){Scanner sc = new Scanner(System.in);System.out.println("输入一个字符串:");String s = sc.nextLine();for(int i = 0;i < s.length();i++){//获取指定索引处的char值char a = s.charAt(i);System.out.print(a+" ");}}
}
结果:
统计字符次数
import java.util.Scanner;public class test1 {public static void main(String[] args){Scanner sc = new Scanner(System.in);System.out.println("输入一个字符串:");String s = sc.nextLine();int bigcount = 0;int smallcount = 0;int numbercount = 0;for (int i = 0;i < s.length();i++){char a = s.charAt(i);if (a >='A'&& a<='Z'){bigcount++;}else if (a >= 'a' && a <= 'z'){smallcount++;}else if (a >= '0' && a <= '9'){numbercount++;}}System.out.println("大写字母:"+bigcount);System.out.println("小写字母:"+smallcount);System.out.println("数字:"+numbercount);}
}
结果:
拼接字符串
public class test2 {public static void main(String[] args){//预先初始化一个数组int[] arr = {2,5,2,7};//调用方法String n = show(arr);System.out.println(n);}//定义一个方法来输出public static String show(int[] a){String s = "[";for (int i = 0;i <a.length;i++){if (i == a.length-1){s = s + a[i];}else{s = s + a[i]+",";}}s = s + "]";return s;}
}
结果:
最后有一个案例是字符串反转,和前边的数组反转有异曲同工之妙,大家可以自己尝试一下
StringBuilder
StringBuilder概述
如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费内存空间,而这种操作还不可避免。那么有没有一种比较好的方式可以解决这个问题呢?答案是肯定的,我们可以通过Java提供的StringBuilder类就来解决这个问题。
StringBuilder是一个可变的字符串类,我们可以把它看成是一个容器
这里的可变指的是StringBuilder对象中的内容是可变的
String和StringBuilder的区别:
String:内容是不可变的StringBuilder:内容是可变的
StringBuilder构造方法
结果:
StringBuilder的添加和反转方法
结果:
这里可以明显的看出来,a,b是同一个对象。帮助我们很好的理解了什么是返回对象本身。
结果:
结果:
因为append()返回的是对象本身,而对象可以调用方法,所以可以连续调用,让返回值作为对象调用方法
结果:
StringBuilder 和String相互转换
1.StringBuilder转换为String
publicString toString():通过 toString()就可以实现把StringBuilder转换为String
2.String转换为StringBuilder
public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder
结果:
可以从输出的结果看出来toString()可以实现把StringBuilder转换为String
结果:
案例
拼接字符串
一开始我没有想到通过转换最终用String接收结果,下面是我的方法:
public class test1 {public static void main(String[] args){//初始化数组int[] arr={2,3,4,5};System.out.println(combine(arr));}//定义拼接字符串方法public static StringBuilder combine(int[] a){StringBuilder s = new StringBuilder();s.append("[");for (int i = 0;i < a.length;i++){if (i == a.length-1){s.append(a[i]);}else {s.append(a[i]).append(",");}}s.append("]");return s;}}
结果:
改进后:
package stringbulider;public class test1 {public static void main(String[] args){//初始化数组int[] arr={2,3,4,5};String s = combine(arr);System.out.println(s);}//定义拼接字符串方法public static String combine(int[] a){StringBuilder s = new StringBuilder();s.append("[");for (int i = 0;i < a.length;i++){if (i == a.length-1){s.append(a[i]);}else {s.append(a[i]).append(",");}}s.append("]");String c = s.toString();return c;}
}
字符串反转
这里我没有使用方法,无法复用
package stringbulider;import java.util.Scanner;public class test2 {public static void main(String[] args){Scanner sc = new Scanner(System.in);System.out.println("输入一段字符串:");String a = sc.nextLine();//把它转化为StingBulider后使用StringBuilder s = new StringBuilder(a);System.out.println(a+"字符串反转结果为:"+s.reverse());}
}
结果:
构造方法后:
import java.util.Scanner;Scanner sc = new Scanner(System.in);System.out.println("输入一段字符串:");String a = sc.nextLine();String b = change(a);System.out.println(a+"字符串反转结果为:"+ b);}public static String change(String a){return new StringBuilder(a).reverse().toString();}
}
集合基础
集合概述
集合类的特点:提供一种存储空问可变的存储模型,存储的数据容量可以发生改变集合类有很多,目前我们先学习一个: ArrayList
ArrayList构造方法和添加方法
结果:
ArrayList常用方法
public boolean remove(0bject o):删除指定的元素,返回删除是否成功
结果:
结果:
public E remove(int index):删除指定索引处的元素,返回被删除的元素
结果:
结果:
这里出现了索引越界
public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
结果:
public E get(int index):返回指定索引处的元素
结果:
案例
存储字符串并遍历
package com.collection;import java.util.ArrayList;public class test {public static void main(String[] args) {ArrayList<String> array = new ArrayList<String>();array.add("小怪兽");array.add("奥特曼");array.add("哈利波特");System.out.println("array:"+array);for (int i = 0;i < array.size();i++){//这里视频是采用的用字符串接受System.out.println("第"+(i+1)+"个元素是:"+array.get(i));}}
}
结果:
存储学生对象并遍历
package com.collection;import java.util.ArrayList;public class test2 {public static void main(String[] args) {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//创建学生对象Student a = new Student("coco",11);Student b = new Student("小怪兽",11);Student c = new Student("奥特曼",22);//添加学生对象到集合中array.add(a);array.add(b);array.add(c);for (int i = 0;i < array.size();i++){Student s = array.get(i);System.out.println("第"+(i+1)+"个学生:"+s.getName()+" "+s.getAge());}}
}
结果:
改进后
package com.collection;import java.util.ArrayList;
import java.util.Scanner;public class test2 {public static void main(String[] args) {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//创建学生对象addStudent(array);addStudent(array);addStudent(array);for (int i = 0;i < array.size();i++){Student s = array.get(i);System.out.println("第"+(i+1)+"个学生:"+s.getName()+" "+s.getAge());}}public static void addStudent(ArrayList<Student> array){Scanner sc = new Scanner(System.in);System.out.print("输入名字:");String name = sc.nextLine();System.out.print("输入年龄:");String age = sc.nextLine();Student s = new Student();s.setName(name);s.setAge(age);array.add(s);}
}
结果:
学生管理系统
当我们从键盘上循环输入一段字符串时要采用next()而不是nextLine(),因为nextLine()上次输入的值后会有/n会被下次循环输入时接受,错误判定为结束,会出现跳过现象。
Student.java
package system;public class Student {//学号private String sid;//姓名private String name;//年龄private String age;//居住地private String address;public Student(){}public Student(String sid,String name,String age,String address){this.sid = sid;this.name = name;this.age = age;this.address = address;}public void setSid(String sid){this.sid = sid;}public String getSid(){return sid;}public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(String age){this.age = age;}public String getAge(){return age;}public void setAddress(String address){this.address = address;}public String getAddress(){return address;}
}
main.java
package system;import java.util.ArrayList;
import java.util.Scanner;public class main {public static void main(String[] args) {//集合对象ArrayList<Student> array = new ArrayList<Student>();while(true){MainInterfance();Scanner sc = new Scanner(System.in);int num = sc.nextInt();switch (num){case 1:System.out.println("添加学生");addStudent(array);break;case 2:System.out.println("删除学生");deleteStudent(array);break;case 3:System.out.println("修改学生");alterStudent(array);break;case 4:System.out.println("查看所有学生");showStudent(array);break;case 5:System.out.println("感谢您的使用!");System.exit(0);}}}//主页面public static void MainInterfance(){System.out.println("-------------欢迎来到学生管理系统-------------");System.out.println("1.添加学生");System.out.println("2.删除学生");System.out.println("3.修改学生");System.out.println("4.查看所有学生");System.out.println("5.退出");System.out.println("请输入你的选择:");}//添加学生public static void addStudent(ArrayList<Student> array){System.out.print("请输入你想添加学生的个数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();for (int i = 1;i <= num;i++){System.out.println("输入添加的第"+i+"个学生的信息");String sid;while (true){System.out.println("输入学号:");sid = sc.next();boolean a = decide(sid,array);if (a){System.out.println("该学号已存在,请重新输入!");}else {break;}}System.out.println("输入姓名:");String name = sc.next();System.out.println("输入年龄:");String age = sc.next();System.out.println("输入居住地:");String address = sc.next();Student s = new Student();s.setSid(sid);s.setAge(age);s.setName(name);s.setAddress(address);array.add(s);}System.out.println("添加成功!");}//删除学生public static void deleteStudent(ArrayList<Student> array){Scanner sc = new Scanner(System.in);System.out.println("输入你想删除的学生的学号:");String sid = sc.next();for (int i = 0;i < array.size();i++){Student s = array.get(i);if (s.getSid().equals(sid)){array.remove(i);break;}else{System.out.println("您输入的学生不存在!");break;}}}//修改学生public static void alterStudent(ArrayList<Student> array) {Scanner sc = new Scanner(System.in);System.out.println("输入你想修改的学生的学号:");String sid = sc.next();System.out.println("输入新姓名:");String name = sc.next();System.out.println("输入新年龄:");String age = sc.next();System.out.println("输入新居住地:");String address = sc.next();Student s = new Student();s.setSid(sid);s.setAge(age);s.setName(name);s.setAddress(address);for (int i = 0; i < array.size(); i++) {Student student = array.get(i);if (student.getSid().equals(sid)) {array.set(i,s);break;}}}//查看学生public static void showStudent(ArrayList<Student> array){if (array.size() == 0){System.out.println("当前没有学生,请先添加学生。");}System.out.println("学号 "+" 姓名 "+" 年龄 "+" 居住地");for(int i = 0;i < array.size();i++){Student s = array.get(i);System.out.println(s.getSid()+" "+s.getName()+" "+s.getAge()+" "+s.getAddress());}}//判断学号重复public static boolean decide(String sid,ArrayList<Student> array){boolean a = false;for (int i = 0;i < array.size();i++){Student s = array.get(i);if(sid.equals(s.getSid())){a = true;break;}}return a;}}
结果:(添加和查看)
结果:(删除和修改)
继承
继承概述
继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法
继承的好处和弊端
好处:
- 提高了代码的复用性
- 提高了代码的维护性
弊端:
继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
继承中变量的访问特点
在子类方法中访问一个变量
- 子类局部范围找
- 子类成员范围找父类成员范围找
super
super关键字的用法和this关键字的用法相似
this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)
随着我的学习更新
零基础JAVA——黑马程序员课程笔记相关推荐
- 零基础学C++——黑马程序员课程笔记(C++核心编程篇)
封面来自互联网侵删 视频地址:点击访问 (我这里开发工具选用VSstudio) 此笔记有三个系列: C++基础语法入门篇 点击查看 C++核心编程篇 C++提高编程篇 本阶段主要针对C++面向对象编程 ...
- 零基础学C++——黑马程序员课程笔记(C++基础语法入门篇)
封面来自互联网侵删 视频地址:点击访问 (我这里开发工具选用VSstudio) 此笔记有三个系列: C++基础语法入门篇 C++核心编程篇 点击查看 C++提高编程篇 文章目录 C++初识 变量 常量 ...
- JavaWeb——黑马程序员课程笔记
视频地址:点击跳转 全程使用开发工具:IDEA Mysql 此篇几乎所有需要的配置文件都可以区黑马公众号找到 目录 JavaWeb介绍 数据库 数据库相关概念 关系型数据库 SQL SQL简介 SQL ...
- 第三章 表格、列表和表单(黑马程序员课程笔记)
1.表格标签 1.2 表格的基本语法 1.3 表头单元格标签 1.4 表格属性 1.5 表格结构标签 1.6 合并单元格 2.列表 2.1 无序列表 2.2 有序列表 2.3 自定义列表 3.表单标 ...
- 从零基础到高级程序员需要走多久?
原文:从零基础到高级程序员需要走多久? 绝大多数计算机专业的学生是零基础,即时通讯软件 其中不乏被调剂的.等到毕业之际,有的成了大神,进入BAT或者google微软,有的还是零基础-- 我高中搞竞赛, ...
- [黑马程序员C++笔记]P72-P83通讯录管理系统
目录 系统需求 1.菜单功能 2.退出功能 3.添加联系人 (1)设计联系人结构体 (2) 设计通讯录结构体 (3)main函数中创建通讯录 (4)封装添加联系人函数 (5 ...
- [黑马程序员C++笔记]P72-P83通讯录管理系统总体概览
系统需求 通讯录是一个可以记录亲人.好友信息的工具. 本教程主要利用C++来实现一个通讯录管理系统 系统中需要实现的功能如下: 添加联系人:向通讯录中添加新人,信息包括(姓名.性别.年龄.联系电话.家 ...
- 黑马程序员jvm笔记总集
黑马程序员jvm笔记(一)–程序计数器 虚拟机栈 堆 黑马程序员jvm笔记(二)–方法区 串池 直接内存 黑马程序员jvm笔记(三)–垃圾回收部分心得 黑马程序员jvm笔记(四)–字节码部分心得 黑马 ...
- SpringCloud学习笔记,课程源自黑马程序员,笔记持续更新中...
@SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式: 学习内容 1.服务拆分-服务远程调用: 2.搭建eureka服务: 2.1.eureka服务注册-client 2 ...
最新文章
- Silverlight C# 游戏开发:未写代码先设计
- [Leetcode]147. Insertion Sort List
- mysql oracle 表空间大小_最简单的查询表空间的使用量、剩余量的方法 - Focus on Oracle、MySQL and GNU/Linux...
- Qt文档阅读笔记-QWebView官方解析与实例
- php新建数据表输入自己相信,php学习记录 - whoAmIR的个人空间 - OSCHINA - 中文开源技术交流社区...
- 小白Linux入门之:常用命令介绍
- ubuntu安装libjasper.so.1,libpng12.so.0
- 网上商城——详细流程
- 关于kindle mobi词典解析
- unity 摄像机导入 3dmax 带fov
- B - Relatively Prime Graph -CodeForces - 1009D-csdn博客
- 吃鸡账号显示连接不了服务器,《绝地求生》“与Steam服务器连接时出现了一个问题”怎么解决...
- 【重点:线程池续】超人气组合:Callable和Future
- Ubuntu 版本 微信
- 学会聆听,职场最重要的事情,没有之一!!!
- 如何从亚马逊抓取产品数据?
- 12.unity编程基础
- 语义激光SLAM论文阅读 Semantic Lidar_based SLAM paper Research
- 2.特定领域知识图谱融合方案:文本匹配算法之预训练Simbert、ERNIE-Gram单塔模型等诸多模型【三】
- NC14670 脸盆da哥的木桶——牛客
热门文章
- ZOJ-4107 Singing Everywhere 2019浙江省省赛
- arcgis根据7参转坐标_应用ArcGIS和COORD软件进行坐标七参数转换的方法
- 什么是对象序列化?如何实现?什么情况下使用?
- ROC曲线绘制原理即AUC的意义详解
- 华为od统一考试B卷【发广播】C++ 实现
- c语言 函数指针 菜鸟教程,C 函数指针与回调函数 | 菜鸟教程
- 二本华南师范计算机考研,适合二本考生考研的4所211学校 考研相对容易
- 【图论刷题-5】力扣 1971. 寻找图中是否存在路径
- 字节跳动,华为,阿里巴巴,小米,腾讯 2021大厂面试经历系列之初、中、高级测试工程师面试题汇总(附答案)
- 双11购物的凑单问题与财务凑数问题