JDK的安装目录
bin 该路径下存放了JDK的各种工具命令,javac和java就放在这个目录
conf 该路径下存放了JDK的相关配置文件
include 该路径下存放了一些平台特定的头文件
jmods 该路径存放了JDK的各种模块
legal 该路径下存放了JDK各模块的授权文档
lib 该路径下存放了JDK工具的一些补充JAR包
常用DOS命令
打开命令提示符窗口
①按下win+R
②输入cmd
③按下回车键
盘符名称:盘符切换。E:回车,表示切换到E盘。
dir:查看当前路径下的内容。
cd目录:进入单级目录。cd itheima。
cd..:回到上一级目录。
cd 目录1\目录2\...:进入多级目录。cd itheima\JavaSE
cd\:回到盘符目录。
cls:清屏。
exit:退出命令提示符窗口。
JRE和JRE
JRE(Java Runtime Environment):是Java程序的运行环境,包含JVM和运行时所需要的核心类库。
JDK(Java Development Kit):是java程序开发工具包,包含JRE和开发人员使用的工具。
我们想要运行一个已有的java程序,那么只需要安装JRE即可。
我们想要运行一个全新的java程序,那么必须安装JDK。
简记:开发:jdk;运行:jre;核心:jvm
IDEA常用快捷键
IDEA结构:
内容辅助键:快速生成语句:快速生成main()方法:main,回车
快速生成输出语句:sout,回车
IDEA创建步骤:1.新建一个项目;
2.新建一个mode;
3.在src中新建一个包package,包名只能是英文的小写或者数字, 分隔“.”;
4.包上new一个class;
5.run运行程序。
package Test01;
public class HelloWorld {
public static void main(String[] args){
System.out.println("HelloWorld!");
}
}
方法基础入门知识:
定义格式:
public static void 方法名称(){
方法体
}
调用格式:
方法名称();
注意事项:1.方法定义的先后顺序无所谓。
2.方法定义必须是挨着的,不能在一个方法的内部定义另外一个方法。
3.方法定义之后,自己不会执行;如果希望执行,一定要进行方法的调用。
关键字的特点:
1.完全小写的字母。
2.在增强版的记事本当中有特殊颜色。
标识符:是指在程序中,我们自己定义的内容。比如类的名字、方法的名字和变量的名字等等, 都是标识符。
HelloWorld案例中, 出现的标识符有类名字HelloWorld。
命名规则:(硬性要求)
标识符不能以数字开头。
标识符不能是关键字。
命名规范:(软性建议)
类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。
方法名规范:同变量名。
常量: 是指在Java程序运行期间固定不变的数据。
常量的分类:
1.字符串常量:凡是用双引号引起来的部分,叫做字符串常量。例如:"abc"、"Hello"、"123"
2.整数常量:直接写上的数字,没有小数点。例如:100、200、0、-250
3.浮点数常量:直接写上的数字,有小数点。例如:2.5、-3.14/0.0
4.字符常量:凡是用单引号引起来的单个字符,叫做字符常量。例如:'A'、'b'、'9'、'中'
5.布尔常量:只有两种取值。true、false
6.空常量:null。代表没有任何数据
数据类型:
基本数据类型【今天重点】
整数型 byte short int long
浮点型 float double
字符型 char
布尔型 boolean
引用数据类型(今后学习)
字符串、数组、类、接口、Lambda
注意事项:
1.字符串不是基本类型,而是引用类型。
2.浮点型可能只是一个近似值,并非精确的值。
3.数据范围与字节数不一定相关,例如float数据范围比long更加广泛,但是float是4字节,long是8字节。
4.浮点数当中默认类型是double。如果一定要使用float类型,需要加上一个后缀F。
如果是整数,默认为int类型,如果一定要使用long类型,需要加上一个后缀L。推荐使用大写字母后缀。
变量: 程序运行期间,内容可以发生改变的量。
创建一个变量并且使用的格式:
数据类型 变量名称;//创建了一个变量
变量名称=数据值;//赋值,将右边的数据值,赋值交给左边的变量
一步到位的格式:
数据类型 变量名称=数据值;//在创建一个变量的同时,立刻放入指定的数据值
使用变量的时候,有一些注意事项:
1.如果创建多个变量,那么变量之间的名称不可以重复。
2.对于float和long类型来说,字母后缀F和L不要丢掉。
3.如果使用byte或者short类型的变量,那么右侧的数据值不能超过左侧类型的范围。
4.没有进行赋值的变量,不能直接使用;一定要赋值之后,才能使用。
5.变量使用不能超过作用域的范围。
【作用域】:从定义变量的一行开始,一直到直接所属的大括号为止。
6.可以通过一个语句来创建多个变量,但是一般情况下不推荐这么写。
当数据类型不一样时,将会发生数据类型转换。
自动类型转换(隐式)
1.特点:代码不需要进行特殊处理,自动完成。
2.规则:数据范围从小到大。
强制数据转换(显式)
1.特点:代码需要进行特殊的格式处理,不能自动完成。
2.格式:范围小的类型 范围小的变量名=(范围小的类型)原本范围大的数据;
注意事项:
1.强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
2.byte/short/char这三种类型都可以发生数学运算。例如加法“+”。
(重要!!!)3.byte/short/char这三种类型在运算的时候,都会被首先提升成为int类型,然后再计算。
4.boolean类型不能发生数据类型转换。ture or false,不能对应0和1。
数字和字符的对照关系表(编码表):
ASCII码表:American Standard Code for Information Interchange,美国信息交换标准代码。
Unicode码表:万国码。也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但是从128开始包含有更多字符。
48-'0'
65-'A'
97-'a'
运算符:进行特定操作的符号。例如:+
表达式:用运算符连起来的式子叫做表达式。例如:20+5。又例如:a+b
四则运算:
加:+
减:-
乘:*
除:/
取模
首先计算得到表达式的结果,然后再打印输出这个结果。
被除数/除数=商...余数
对于一个整数的表达式来说,除法用的是整除,整数除以整数,结果仍然是整数。只看商,不看余数。
只有对于整数的除法来说,取模运算符才有余数的意义。
注意事项:
1.一旦运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。
四则运算当中的加号“+”有常见的三种用法:
1.对于数值来说,那就是加法。
2.对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算。
char类型字符,和int类型数字,之间的对照关系表:ASCII、Unicode。
3.对于字符串String(首字母大写,并不是关键字)来说,加号代表字符串连接操作。
任何数据类型和字符串进行连接的时候,结果都会变成字符串。
自增运算符:++
自减运算符:--
基本含义:让一个变量涨一个数字1,或者让一个变量降一个数字1。
使用格式:写在变量名称之前,或者写在变量名称之后。例如:++num,也可以num++。
使用方式:
1.单独使用:不和其他任何操作混合,自己独立成为一个步骤。
2.混合使用:和其他操作混合,例如与赋值混合,或者与打印操作混合,等。
使用区别:
1.在单独使用的时候,前++和后++没有任何区别。也就是:++num;和num++;是完全一样的。
2.在混合的时候,有【重大区别】
A.如果是【前++】,那么变量【立刻马上+1】,然后拿着结果进行使用。【先加后用】
B.如果是【后++】,那么首先使用变量本来的数值,【然后再让变量+1】。【先用后加】
注意事项:
只有变量才能使用自增、自减运算符。常量不可发生改变,所以不能用。
赋值运算符分为:
基本赋值运算符:
比较运算符:注意事项:
1.比较运算符的结果一定是一个boolean值,成立就是true,不成立就是false
2.如果进行多次判断,不能连着写。
逻辑运算符:与(并且)&&
或(或者)||
非(取反)!
与“&&”,或者“||”,具有短路效果:如果根据左边已经可以判断得到最终结果,那么右边的代码将不再执行,从而节省一定的性能。
注意事项:1. 逻辑运算符只能用于boolean值。
2.与、或需要左右各自有一个boolean值,但是取反只要有唯一的一个boolean值即可。
3.与、或两种运算符,如果有多个条件,可以连续写。
两个条件:条件A&&条件B
多个条件:条件A&&条件B&&条件C
TIPS:
对于1<x&&x<3的情况,应该拆成两个部分,然后使用运算符连接起来。
一元运算符:只需要一个数据就可以进行操作的运算符,例如:取反!、自增++、自减--
二元运算符:需要两个数据才可以进行操作的运算符。例如:加法+、赋值=
三元运算符(格式):数据类型 变量名称=条件判断?表达式A:表达式B
流程:首先判断条件是否成立:
如果成立为true,那么将表达式A的值赋给左侧的变量;
如果不成立为false,那么将表达式B的值赋给左侧的变量;
二者选其一。
注意事项:
1.必须同时保证表达式A和表达式B都符合左侧数据类型的要求。
定义一个方法的格式:
public static void 方法名称(){
方法体
}
方法名称的命名规则和变量一样,使用小驼峰。
方法体:也就是大括号当中可以包含任意条语句。
注意事项:
1.方法定义的先后顺序无所谓。
2.方法的定义不产生嵌套包含关系。
3.方法定义好了之后,不会执行的。如果想要执行,一定要进行方法的【调用】。
如何调用方法,格式:
方法名称();
在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,
那么编译器javac将会直接将若干个常量表达式计算得到结果。
short result=5+8;//等号右边全都是常量,没有任何变量参与运算
编译之后,得到的.class字节码文件当中相当于【直接就是】:
short result=13;
右侧的常量结果数值,没有超过左侧范围,所以正确。
这称为“编译器的常量优化”。
但是注意:一旦表达式当中有变量参与,那么久不能进行这种优化了。
顺序结构:
选择结构:
判断语句:
选择语句:
switch语句使用的注意事项:
1.多个case后面的数值不可以重复。
2.switch后面小括号当中只能是下列数据类型:
基本数据类型:byte/short/char/int
引用数据类型:String字符串、enum枚举
3.switch语句格式可以很灵活:前后顺序可以颠倒,而且break语句还可以省略。
“匹配哪一个case就从哪一个位置向下执行,直到遇到了break或者整体结束为止。”
循环语句:
循环结构的基本组成部分,一般可以分成四部分:
1.初始化语句:在循环开始最初执行,而且只做唯一一次。
2.条件判断:如果成立,则循环继续;如果不成立,则循环退出。
3.循环体:重复要做的事情内容,若干行语句。
4.步进语句:每次循环之后都要进行的扫尾工作,每次循环结束之后都要执行一次。
while循环有一个标准格式,还有一个扩展格式。
标准格式:
while(条件判断){
循环体
}
扩展格式:
初始化语句:
while(条件判断){
循环体;
步进表达式;
}
do-while循环的标准格式;
do{
循环体
}while(条件判断);
扩展格式:
初始化语句
do{
循环体
步进语句
}while(条件判断);
三种循环的区别:
1.如果条件判断从来没有满足过,那么for循环将会执行0次,但是do-while循环会执行至少一次。
2.for循环的变量在小括号当中有定义,只有循环内部才可以使用。while循环和do-while循环初始化语句本来就在外面,所以出来循环之后还可以继续使用。
break关键字的用法有常见的两种:
1.可以用在switch语句当中,一旦执行,整个switch语句立刻结束。
2.还可以用在循环语句当中,一旦执行,整个循环语句立刻结束,打断循环。
关于循环的选择,有一个小建议:
凡是次数确定的场景多用for循环;否则多用while循环。
另一种是循环控制语句是continue关键字。
一旦执行,立刻跳过当前次循环剩余内容,马上开始下一次循环。
永远停不下来的循环,叫做死循环。
死循环的标准格式:
while(true){
循环体
}
嵌套循环。
修饰符 返回值类型 方法名称(参数类型 参数名称,...){
方法体
return 返回值;
}
修饰符:现阶段的固定写法,public static
返回值类型:也就是方法最终产生的数据结果是什么类型
方法名称:方法的名字,规则和变量一样,小驼峰
参数类型:进入方法的数据是什么类型
参数名称:进入方法的数据对应的变量名称
PS:参数如果有多个,使用逗号进行分隔
方法体:方法需要做的事情,若干行代码
return:两个作用,第一停止当前方法,第二将后面的返回值还给调用处
返回值:也就是方法执行后最终产生的数据结果
注意:return后面的“返回值”,必须和方法名称前面的“返回值类型”保持对应。
定义一个两个int数字相加的方法。三要素:
返回值类型:int
方法名称:sum
参数列表:int a,int b
方法的三种调用格式:
1.单独调用:方法名称(参数);
2.打印调用:System.out.println(方法名称(参数));
3.赋值调用:数据类型 变量名称=方法名称(参数);
注意:此前学习的方法,返回值固定写为void,这种方法只能够单独调用,不能进行打印调用或者赋值调用。
对比有参数和无参数:
有参数:小括号当中有内容,当一个方法需要一些数据条件,才能完成任务的时候,就是有参数。
例如两个数字相加,必须知道两个数字是各自多少,才能相加。
无参数:小括号当中留空。一个方法不需要任何数据条件,自己就能独立完成任务,就是无参数。
void和int,有返回值和无返回值的区别?
使用方法的时候,注意事项:
1.方法应该定义在类当中,但是不能在方法中再定义方法。不能嵌套。
2.方法定义的前后顺序无所谓。
3.方法定义之后不会执行,如果希望执行一定要调用:单独调用、打印调用、赋值调用。
4.如果方法有返回值,那么必须写上“return 返回值;”,不能没有。
5.return后面的返回值数据,必须和方法的返回值类型,对应起来。
6.对于一个void没有返回值的方法,不能写return后面的返回值,只能写return自己。
7.对于void方法当中最后一行的return可以省略不写。
8.一个方法当中可以有多个return
对于功能类似的方法来说,因为参数列表不一样,却需要记住那么多不同的方法名称,太麻烦。
方法的重载(Overload):多个方法的名称一样,但是参数列表不一样。
好处:只需要记住唯一一个方法名称,就可以实现类似的多个功能。
方法重载与下列因素相关:
1.参数个数不同
2.参数类型不同
3.参数的多类型顺序不同
方法重载与下列因素无关:
1.与参数的名称无关
2.与方法的返回值类型无关
数组的初始化:在内存中创建一个数组,并且向其中创建一个数组,并且向其中赋予一些默认值。
两种常见的初始化方式:
1.动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素个数。
2.静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。
动态初始化数组的格式:
数据类型[] 数组名称=new 数据类型[数组长度];
解析含义:
左侧数据类型:也就是数组当中保存的数据,全都是统一的什么类型
左侧的中括号:代表我是一个数组
左侧数组名称:给数组取一个名字
右侧的new,代表创建数组的动作
右侧数据类型:必须和左边的数据类型保持一致
右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个int数字
静态初始化基本格式:
标准格式:
数据类型[] 数组名称=new 数据类型[] {元素1,元素2,...};
省略格式:
数据类型[]
注意事项:
1.虽然静态初始化没有直接告诉长度,但是根据大括号里面的元素具体内容,也可以自动推算出来长度。
2.静态初始化标准格式可以拆分成两个步骤。
3.动态初始化也可以拆分成两个步骤。
4.静态初始化一旦使用省略格式,就不能拆分成两个步骤了。
使用建议:
如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。
访问数组元素的格式:数组名称[索引值]
索引值:就是一个int数字,代表数组当中元素的编号。
【注意】索引值从0开始,一直到“数组的长度-1”为止。
使用动态初始化数组的时候,其中的元素将会自动拥有一个默认值。规则如下:
如果是整数类型,那么默认为0;
如果是浮点类型,那么默认为0.0;
如果是字符类型,那么默认为'\u0000';
如果是布尔类型,那么默认为false;
如果是引用类型,那么默认为null。
注意事项:
静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成了大括号当中的具体数值。
Java的内存需要划分成为五个部分:
1.栈(Stack):存放的都是方法中的局部变量。方法的运行一定要在栈当中。
局部变量:方法的参数,或者是方法{}内部的变量。
作用域:一旦超出作用域,立刻从栈内存当中消失。
2.堆(Heap):凡是new出来的东西,都在堆当中。
堆内存里面的东西都有一个地址值:16进制
堆内存里面的数据,都有默认值。规则:
如果是整数 默认为0
如果是浮点数 默认为0.0
如果是字符类型 默认为'\u0000';
如果是布尔类型 默认为false;
如果是引用类型 默认为null。
3.方法区(Method Area):存储.class相关信息,包含方法的信息。
4.本地方法栈(Native Method Stack):与操作系统相关。
5.寄存器(pc Register):与CPU相关。
数组的索引编号从0开始,一直到“数组的长度-1”为止。
如果访问数组元素的时候,索引编号并不存在,那么将会发生数组索引越界异常。
ArrayIndexOutOfBoundsException
原因:索引编号写错了。
所有的引用类型变量,都可以赋值为一个null值。但是代表其中什么都没有。
数组必须进行new初始化才能使用其中的元素。
如果只是赋值了一个null,才能进行new创建,
那么将会发生:
空指针异常 NullPointerException
原因:忘了new
解决:补上new
如何获取数组的长度,格式:
数组名称.length
这将会得到一个int数字,代表数组的长度。
数组一旦创建,程序运行期间,长度不可改变。
一个方法可以有0、1、多个参数:但是只能有0或者1个返回值,不能有多个返回值。
如果希望一个方法当中产生了多个结果数据类型进行返回,怎么办?
解决方案:使用一个数组作为返回值类型即可。
面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节。
面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事。
类:是对一类事物的描述,是抽象的。
对象:是一类事物的实例,是具体的。
类是对象的模板,对象是类的实体。
注意事项:
【1.成员变量是直接定义在类当中的,在方法外边。】
【2.成员方法不要写static关键字。】
通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。
1.导包:也就是指出需要使用的类,在什么位置。
import 包名称.类名称;
import cn.itcast.day06.demo01.Student;
对于和当前类属于同一个包的情况,可以省略导包语句不写。
2.创建,格式:
类名称 对象名=new 类名称();
Student stu=new Student();
3.使用,分两种情况:
使用成员变量:对象名.成员变量名
使用成员方法:对象名.成员方法名(参数)
(也就是,想用谁,就用对象名点谁。)
注意事项:
【如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样。】
定义一个类,用来模拟“手机”事物。
属性:品牌、价格、颜色
行为:打电话、发短信
对应到类当中:
成员变量(属性):
String brand;//品牌
double price;//价格
String color;//颜色
成员方法(行为):
pubilc void call(String who){}//打电话
public void sendMessage(){}//群发短信
局部变量和成员变量:
1.定义的位置不一样【重点】
局部变量:在方法的内部
成员变量:在方法的外部,直接写在类当中
2.作用范围不一样【重点】
局部变量:只有方法当中才可以使用,出了方法就不能再用
成员变量:整个类都可以通用
3.默认值不一样【重点】
局部变量:没有默认值,如果要想使用,必须手动进行赋值
成员变量:如果没有赋值,会有默认值,规则和数组一样
4.内存的位置不一样(了解)
局部变量:位于栈内存
成员变量:位于堆内存
5.生命周期不一样(了解)
局部变量:随着方法进栈而诞生,随着方法出栈而消失(短)
成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失(长)
面向对象的三大特征:封装、继承、多态。
封装性在JAVA当中的体现:
1.方法就是一种封装
2.关键字private也是一种封装
封装就是将一些细节信息隐藏起来,对于外界不可见。
问题描述:定义Person的年龄时,无法阻止不合理的数值被设置进来。
解决方案:用private关键字将需要保护的成员变量进行修饰。
一旦使用了private进行修饰,那么本类当中仍然可以随意访问。
但是!超出了本类范围之外就不能再直接访问了。
间接访问private成员变量,就是定义一对儿Getter/Setter方法。
对于基本类型当中的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变。
当方法的局部变量和类的成员变量重名的时候,根据“就近原则”,优先使用局部变量。
如果需要访问本类当中的成员变量,需要使用格式:
this.成员变量名
“通过谁调用的方法,谁就是this。”
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。
格式:public 类名称(参数类型 参数名称){
方法体
}
注意事项:
1.构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
2.构造方法不要写返回值类型,连void都不写
3.构造方法不能return一个具体的返回值
4.如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数、方法体什么事情都不做。
public Student(){}
5.一旦编写了至少一个构造方法,那么编译器将不再赠送。
6.构造方法也是可以进行重载的。
重载:方法名称相同,参数列表不同。
一个标准的类通常要拥有下面四个组成部分:
1.所有的成员变量都要使用private关键字修饰;
2.为每一个成员变量编写一对儿Getter/Setter方法;
3.编写一个无参数的构造方法;
4.编写一个全参数的构造方法。
这样标准的类也叫做Java Bean。
Scanner类的功能:可以实现键盘输入数据,到程序当中。
引用类型的一般使用步骤:
1.导包
import 包路径.类名称;
如果需要使用的目标类,和当前类位于同一个包下,则可以省略导包语句不写。
只有java.lang包下的内容不需要导包,其他的包都需要import语句。
2.创建
类名称 对象名=new 类名称(); (备注:System.in代表从键盘输入)
3.使用
对象名.成员方法名()
获取键盘输入的一个int数字:int num=sc.nextInt();
获取键盘输入的一个字符串:String str=sc.next();
题目:
键盘输入两个int数字,并且求出和值。
思路:
1.既然需要键盘输入,那么就用Scanner
2.Scanner的单个步骤:导包、创建、使用
3.需要的是两个数字,所以要调用两次nextInt方法
4.得到了两个数字,就需要加在一起
5.将结果打印输出
package Test02;
import java.util.Scanner;
public class Demo02ScannerSum {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个数字:");
int a=sc.nextInt();
System.out.println("请输入第二个数字:");
int b=sc.nextInt();
int result=a+b;
System.out.println("结果是:"+result);
}
}
题目:
键盘输入是哪个int数字,然后求出其中的最大值。
思路:
1.既然是键盘输入,肯定需要用到Scanner
2.Scanner三个步骤:导包、创建、使用nextInt()方法
3.既然是三个数字,那么调用三次nextInt()方法,得到三个int变量
4.无法同时判断三个数字谁最大,应该转换成为两个步骤:
4.1 首先判断前两个当中谁最大,拿到前两个的最大值
4.2 拿着前两个中的最大值,再和第三个数字比较,得到三个数字当中的最大值
5.打印最终结果
package Test02;
import java.util.Scanner;
public class Demo03ScannerMax {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入第一个数字");
int a=sc.nextInt();
System.out.println("请输入第二个数字");
int b=sc.nextInt();
System.out.println("请输入第三个数字");
int c=sc.nextInt();
int temp=a>b?a:b;
int max=temp>c?temp:c;
System.out.println("最大值是:"+max);
}
}
创建对象的标准格式:
类名称 对象名=new 类名称();
匿名对象就是只有右边的对象,没有左边的名字和赋值运算符。
new 类名称();
注意事项:匿名对象只能使用唯一的一次,下次再用不得不创建一个新对象。
使用建议:如果确定有一个对象只需要使用唯一的一次,就可以匿名对象。
package Test02;
import java.util.Scanner;
public class Demo02Anonymous {
public static void main(String[] args) {
//普通使用方式
// Scanner sc=new Scanner(System.in);
// int sum=sc.nextInt();
//匿名对象的方式
// int num=new Scanner(System.in).nextInt();
// System.out.println("输入的是:"+num);
//使用一般写法传入参数
// Scanner sc=new Scanner(System.in);
// methodParam(sc);
//使用匿名对象来进行传参
// methodParam(new Scanner(System.in));
Scanner sc=methodReturn();
int num=sc.nextInt();
System.out.println("输入的是:"+num);
}
public static void methodParam(Scanner sc) {
int num=sc.nextInt();
System.out.println("输入的是:"+num);
}
public static Scanner methodReturn(){
// Scanner sc=new Scanner(System.in);
// return sc;
return new Scanner(System.in);
}
}
Random类用来生成随机数字。使用起来也是三个步骤:
1.导包
import java.uti.Random;
2.创建
Ramdom r=new Random();//小括号当中留空即可
3.使用
获取一个随机的int数字(范围是int所有范围,有正负两种):int num=r.nextInt()
获取一个随机的int数字(参数代表了范围,左闭右开区间):int num=r.nextInt(3)
实际上代表的含义是:[0,3),也就是0~2
题目要求:
根据int变量n的值,来获取随机数字,范围是[1,n],可以取到也可以取到n。
思路:
1.定义一个int变量n,随意赋值
2.要使用Random:三个步骤:导包、创建、使用
3.如果写10,那么就是0~9,然而想要的是1~10,可以发现:整体+1即可。
打印随机数字
package Test02;
import java.util.Random;
public class Demo03Random {
public static void main(String[] args) {
int n=5;
Random r=new Random();
for (int i = 0; i < 100; i++) {
//本来范围是[0,n),整体+1之后变成了[1,n+1),也就是[1,n]
int result=r.nextInt(n)+1;
System.out.println(result);
}
}
}
题目:
用代码模拟数字的小游戏。
思路:
1.首先需要产生一个随机数字,并且一旦产生不再变化。用Random的nextInt方法
2.需要键盘输入,所以用到了Scanner
3.获取键盘输入的数字,用Scanner当中的nextInt方法
4.已经得到了两个数字,判断(if)一下:
如果太大了,提示太大,并且重试;
如果太小了,提示太小,并且重试;
如果猜中了,游戏结束。
5.重试就是再来一次,循环次数不确定,用while(true)。
package Test02;
import java.util.Random;
import java.util.Scanner;
public class Demo04RandomGame {
public static void main(String[] args) {
Random r = new Random();
int randomNum = r.nextInt(100) + 1;//[1.100]
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入你猜测的数字:");
int guessNum = sc.nextInt();//键盘输入猜测的数字
if (guessNum > randomNum) {
System.out.println("太大了,请重试。");
} else if (guessNum < randomNum) {
System.out.println("太小了,请重试。");
} else {
System.out.println("恭喜你,猜中啦!");
break; //如果猜中,不再重试
}
}
System.out.println("游戏结束。");
}
}
题目: 定义一个数组,用来存储3个Person对象。
数组有一个缺点:一旦创建,程序运行期间长度不可以发生改变。
数组的长度不可以发生改变。
但是ArrayList集合的长度是可以随意变化的。
对于ArrayList来说,有一个尖括号<E>代表泛型。
泛型:也就是装在集合当中的所有元素,全都是统一的什么类型。
注意:泛型只能是引用类型,不能是基本类型。
注意事项:
对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。
如果内容是空,得到的是中括号:[]
ArrayList当中的常用方法有:
public boolean add(E e):向集合当中添加元素,参数的类型和泛型一致。返回值代表添加是否成功。
备注:对于ArrayList集合来说,add添加动作一定是成功的,所以返回值可用不用。
但是对于其他集合(今后学习)来说,add添加动作不一定成功。
public E get(int index):从集合当中获取元素,参数是索引编号,返回值就是对应位置的元素。
public E remove(int index):从集合当中删除元素,参数是索引编号,返回值就是被删除掉的元素。
public int size():获取集合的尺寸长度,返回值是集合中包含的元素个数。
如果希望向集合ArrayList当中存储基本类型数据,必须使用基本类型对应的“包装类”。
基本类型 包装类(引用类型,包装类都位于java.lang包下)
byte Byte
short Short
int Integer 【特殊】
long Long
float Float
double Double
char Character 【特殊】
boolean Boolean
从JDK1.5+开始,支持自动装箱、自动拆箱。
自动装箱:基本类型-->包装类型
自动拆箱:包装类型-->基本类型
package Test03;
import java.util.ArrayList;
public class Demo05ArrayListBasic {
public static void main(String[] args) {
ArrayList<String>listA=new ArrayList<>();
//错误写法!泛型只能是引用类型,不能是基本类型
//Arrayist<int> listB=new ArrayList<>();
ArrayList<Integer> listC=new ArrayList<>();
listC.add(100);
listC.add(200);
System.out.println(listC);//[100,200]
int num=listC.get(1);
System.out.println("第1号元素是:"+num);
}
}
题目:
生成6个1~33之间的随机整数,添加到集合,并遍历集合。
思路:
1.需要存储6个数字,创建一个集合,<Integer>
2.产生随机数,需要用到Random
3.用循环6次,来产生6个随机数字:for循环
4.循环内调用r.nextInt(int n),参数是33,0~32,整体+1才是1~33
5.把数字添加到集合中:add
6.遍历集合:for、size、get
package Test03;
import java.util.ArrayList;
import java.util.Random;
public class Demo01ArrayListRandom {
public static void main(String[] args) {
ArrayList<Integer>list=new ArrayList<>();
Random r=new Random();
for(int i=0;i<6;i++){
int num=r.nextInt(33)+1;
list.add(num);
}
//遍历集合
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
题目:
自定义4个学生对象,添加到集合,并遍历。
思路:
1.自定义Student学生类,四个部分。
2.创建一个集合,用来存储学生对象。泛型:<Student>
3.根据类,创建4个学生对象。
4.将4个学生对象添加到集合中:add
5.遍历集合:for、size、get
package Test03;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package Test03;
import java.util.ArrayList;
public class Demo02ArrayListStudent {
public static void main(String[] args) {
ArrayList<Student>list=new ArrayList<>();
Student one=new Student("a",20);
Student two=new Student("b",21);
Student three=new Student("c",22);
Student four=new Student("d",23);
list.add(one);
list.add(two);
list.add(three);
list.add(four);
//遍历集合
for(int i=0;i<list.size();i++){
Student stu=list.get(i);
System.out.println("姓名:"+stu.getName()+",年龄"+stu.getAge());
}
}
}
题目:
定义以指定格式打印集合的方法(ArrayList类型作为参数),使用@分隔每个元素。
格式参照{元素@元素@元素}。
System.out.println(list); [10,20,30]
printArrayList(list); [10@20@30]
定义方法的三要素:
返回值类型:只是进行 打印而已,没有运算,没有结果:所以用void
方法名称:printArrayList
参数列表:ArrayList
package Test03;
import java.util.ArrayList;
public class Demo03ArrayListPrint {
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println(list);//[a,b,c,d]
printArrayList(list);
}
public static void printArrayList(ArrayList<String>list){
//{a@b@c@d}
System.out.print("{");
for (int i = 0; i < list.size(); i++) {
String name=list.get(i);
if(i==list.size()-1){
System.out.println(name+"}");
}else{
System.out.print(name+"@");
}
}
}
}
//集合也可以作为方法的参
题目:
用一个大集合存入20个随机数字,然后筛选其中的偶数元素,放到小集合当中。
要求用自定义的方法来实现筛选。
分析:
1.需要创建一个大集合,用来存储int数字,<Integer>
2.随机数字就用Random nextInt
3.循环20次,把随机数字放入大集合:for循环、add方法
4.定义一个方法,用来进行筛选。
筛选:根据大集合,筛选符合要求的元素,得到小集合。
三要素:
返回值类型:ArrayList小集合(里面元素个数不确定)
方法名称:getSmallList
参数列表:ArrayList大集合(装着20个随机数字)
5.判断(if)是偶数,num%2==0
6.如果是偶数,就放到小集合当中,否则不放。
package Test03;
import java.util.ArrayList;
import java.util.Random;
public class Demo04ArrayListReturn {
public static void main(String[] args) {
ArrayList<Integer>bigList=new ArrayList<>();
Random r=new Random();
for (int i = 0; i < 20; i++) {
int num=r.nextInt(100)+1;//1~100
bigList.add(num);
}
ArrayList<Integer>smallList=getSmallList(bigList);
System.out.println("偶数总共有多少个:"+smallList.size());
for (int i = 0; i < smallList.size(); i++) {
System.out.println(smallList.get(i));
}
}
//这个方法,接收大集合参数,返回小集合结果
public static ArrayList<Integer>getSmallList(ArrayList<Integer>bigList){
//创建一个小集合,用来装偶数结果
ArrayList<Integer>smallList=new ArrayList<>();
for (int i = 0; i < bigList.size(); i++) {
int num=bigList.get(i);
if(num%2==0){
smallList.add(num);
}
}
return smallList;
}
}
java.lang.String类代表字符串。
API当中说:Java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现。
其实就是说:程序当中所有的双引号字符串,都是String类的对象。(就算没有new,也照样是。)
字符串的特点:
1.字符串的内容永不可变。【重点】
2.正是因为字符串不可 改变,所以字符串是可以共享使用的。
3.字符串效果上相当于char[]字符数组,但是底层原理是byte[]字节数组。
创建字符串的常见3+1种方式。
三种构造方法:
public String():创建一个空白字符,不含有任何内容。
public String(char[] array):根据字符数组的内容,来创建对应的字符串。
public String(byte[] array):根据字节数组的内容,来创建对应的字符串。
一种直接创建:
String str="Hello";//右边直接用双引号
注意:直接写上双引号,就是字符串对象。
package Test03;
public class Demo01String {
public static void main(String[] args) {
//使用空参构造
String str1=new String();//小括号留空,说明字符串什么内容都没有
System.out.println("第1个字符串:"+str1);
//根据字符数组创建字符串
char[] charArray={'A','B','C'};
String str2=new String(charArray);
System.out.println("第2个字符串:"+str2);
//根据字节数组创建字符串
byte[] byteArray={97,98,99};
String str3=new String(byteArray);
System.out.println("第3个字符串:"+str3);
//直接创建
String str4="Hello";
System.out.println("第4个字符串"+str4);
}
}
字符串常量池:程序当中直接写上的双引号字符串,就在字符串常量池中。
对于基本类型来说,==是进行数值的比较。
对于引用类型来说,==是进行【地址值】的比较。
package Test03;
public class Demo02StringPool {
public static void main(String[] args) {
String str1="abc";
String str2="abc";
char[] charArray={'a','b','c'};
String str3=new String(charArray);
System.out.println(str1==str2);//true
System.out.println(str1==str3);//false
System.out.println(str2==str3);//false
}
}
1.对于引用类型来说,==进行的是地址值的比较。
2.双引号直接写的字符串在常量池当中,new的不在池当中。
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法:
public boolean equals(Object):参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true;否则返回false。
注意事项:
1.任何对象都能用Object进行接收。
2.equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。
3.如果比较双方一个常量一个变量,推荐把常量字符串写在前面。
推荐:"abc".equals(str) 不推荐:str.equals("abc")
public boolean equalsIgnoreCase(String str):忽略大小写,进行内容的比较。
package Test03;
public class Demo01StringEquals {
public static void main(String[] args) {
String str1="Hello";
String str2="Hello";
char[] charArray={'H','e','l','l','o'};
String str3=new String(charArray);
System.out.println(str1.equals(str2));//true
System.out.println(str2.equals(str3));//true
System.out.println(str3.equals("Hello"));//true
System.out.println("Hello".equals(str1));//true
String str4="hello";
System.out.println(str1.equals(str4));//false
System.out.println("====================");
String str5=null;
System.out.println("abc".equals(str5));//推荐:false
// System.out.println(str5.equals("abc"));//不推荐:报错,空指针异常NullPointerException
System.out.println("==============");
String strA="Java";
String strB="java";
System.out.println(strA.equals(strB));//false,严格区分大小写
System.out.println(strA.equalsIgnoreCase(strB));//true,忽略大小写
}
}
String当中与获取相关的常用方法有:
public int length():获取字符串当中含有的字符个数,拿到字符串长度。
public String concat(String str):将当前字符串和参数字符串拼接成为返回值新的字符串。
public char charAt(int index):获取指定索引位置的单个字符。(索引从0开始。)
public int indexOf(String str):查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回-1值。
package Test03;
public class Demo02StringGet {
public static void main(String[] args) {
//获取字符串的长度
int length="gsndjgnwigfnhiwu".length();
System.out.println("字符串的长度是:"+length);
//拼接字符串
String str1="Hello";
String str2="World";
String str3= str1.concat(str2);
System.out.println(str1);//Hello,原封不动
System.out.println(str2);//World,原封不动
System.out.println(str3);//HelloWorld,新的字符串
System.out.println("==========");
//获取指定索引位置的单个字符
char ch="Hello".charAt(1);
System.out.println("在1号索引位置的字符是:"+ch);
System.out.println("==================");
//查找参数字符串在本来字符串当中出现的第一次索引位置
//如果根本没有,返回-1值
String original="HelloWorld";
int index=original.indexOf("llo");
System.out.println("第一次索引值是:"+index);//2
System.out.println("HelloWorld".indexOf("abc"));//-1
}
}
字符串的截取方法:
public String substring(index):截取从参数位置一直到字符串
public String substring(int begin,int end):截取从begin开始,一直到end结束,中间的字符串。
备注:[begin,end),包含左边,不包含右边。
package Test03;
public class Demo03substring {
public static void main(String[] args) {
String str1="HelloWorld";
String str2=str1.substring(5);
System.out.println(str1);//HelloWorld,原封不动
System.out.println(str2);//World,新字符串
System.out.println("===============");
String str3=str1.substring(4,7);
System.out.println(str3);//oWo
System.out.println("===============");
//下面这种写法,字符串的内容仍然是没有改变的
//下面有两个字符串:"Hello","Java"
//strA当中保存的是地址值。
//本来地址是Hello的0X666,
//后来地址变成了Java的0x999
String strA = "Hello";
System.out.println(strA);
strA = "Java";
System.out.println(strA);
}
}
Srting当中与转换相关的常用方法有:
public char[] toCharArray():将当前字符串拆分成为字符数组作为返回值。
public byte[] getBytes():获得当前字符串底层的字节数组。
public String replace(CharSequence oldString,CharSequence newString),
将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串。
备注:CharSquence意思就是说可以接受字符串类型。
package Test03;
import java.nio.charset.StandardCharsets;
public class Demo04StringConvert {
public static void main(String[] args) {
//转换成为字符数组
char[] chars="Hello".toCharArray();
System.out.println(chars[0]);//H
System.out.println(chars.length);//5
System.out.println("==============");
//转换成为字节数组
byte[] bytes="abc".getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);//97
//98
//99
}
System.out.println("======================");
//字符串的内容替换
String str1="How do you do?";
String str2=str1.replace("o","*");
System.out.println(str1);//How do you do?
System.out.println(str2);//H*w d* y*u d*?
System.out.println("===============");
String lang1="早上好!晚上好!";
String lang2=lang1.replace("晚上好!","***");
System.out.println(lang2);//早上好!***
}
}
分割字符串的方法:
public String[] split(String regex):按照参数的规则,将字符串切分成为若干部分。
注意事项:
split方法的参数其实是一个“正则表达式”,今后学习。
今天要注意:如果按照英文句点“.”进行切分,必须写“\\.”(两个反斜杠)
package Test03;
import com.sun.org.apache.xpath.internal.objects.XString;
public class Demo05StringSplit {
public static void main(String[] args) {
String str1="aaa,bbb,ccc";
String[] array1=str1.split(",");
for (int i = 0; i < array1.length; i++) {
System.out.println(array1[i]);//aaa
//bbb
//ccc
}
System.out.println("===================");
String str2="aaa bbb ccc";
String[] array2=str2.split(" ");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]);//aaa
//bbb
//ccc
}
System.out.println("===================");
String str3="XXX.YYY.ZZZ";
String[] array3= str3.split("\\.");
System.out.println(array3.length);//3
for (int i = 0; i < array3.length; i++) {
System.out.println(array3[i]);//XXX
//YYY
//ZZZ
}
}
}
题目:
定义一个方法,把数组{1,2,3}按照指定格式拼接成一个字符串。格式参考如下:[word1#word2#word3]。
分析:
1.首先准备一个int[]数组,内容是1、2、3
2.定义一个方法,用来将数组变成字符串
三要素:
返回值类型:String
方法名称:fromArrayToString
参数列表:int[]
3.格式:[word1#word2#word3]
用到:for循环、字符串拼接、每个数组元素之前都有一个word字样、分割使用的是#、区分一下是不是最后一个
4.调用方法,得到返回值,并打印结果字符串
package Test03;
public class Demo06StringPractise {
public static void main(String[] args) {
int[] array={1,2,3};
String result=fromArrayToString(array);
System.out.println(result);
}
public static String fromArrayToString(int[] array){
String str="[";
for (int i = 0; i < array.length; i++) {
if ((i==array.length-1)) {
str += "word" + array[i] + "]";
} else{
str+="word"+array[i]+"#";
}
}
return str;
}
}
题目:
键盘输入一个字符串,并且统计其中各字符出现的次数
种类有:大写字母、小写字母、数字、其他
思路:
1.既然用到键盘输入,肯定是Scanner
2.键盘输入的是字符串,那么:String str=sc.next();\
3.定义四个变量,分别代表四种字符各自出现的次数
4.需要对字符串一个字、一个字的检查,String-->char[],方法就是toCharArray()
5.遍历char[]字符数组,对当前字符的种类进行判断,并且用四个变量进行++动作
6.打印输出四个变量,分别代表四种字符出现次数
package Test03;
import java.util.Scanner;
public class Demo07StringCount {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String input=sc.next();//获取键盘输入的一个字符串
int countUpper=0;//大写字母
int countLower=0;//小写字母
int countNumber=0;//数字
int countOther=0;//其他字符
char[] charArray=input.toCharArray();
for (int i = 0; i < charArray.length; i++) {
char ch=charArray[i];//当前单个字符
if ('A'<=ch&&ch<='Z'){
countUpper++;
}else if ('a'<=ch&&ch<='z'){
countLower++;
}else if ('0'<=ch&&ch<='9'){
countNumber++;
}else{
countOther++;
}
}
System.out.println("大写字母有:"+countUpper);
System.out.println("小写字母有:"+countLower);
System.out.println("数字有:"+countNumber);
System.out.println("其他字符有:"+countOther);
}
}
如果一个成员变量使用了static关键字 ,那么这个变量不再属于对象自己,而是属于所在的类。多个对象共享同一份数据。
package Test04;
public class Student {
private int id;//学号
private String name;//姓名
private int age;//年龄
static String room;//所在教室
private static int idCounter=0;//学号计数器,每当new了一个新对象的时候,计数器++
public Student() {
this.id=++idCounter;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id=++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package Test04;
public class Demo01StaticField {
public static void main(String[] args) {
Student two=new Student("hr" ,16);
two.room="101";
System.out.println("姓名:"+two.getName()
+",年龄:"+two.getAge()+",教室:"+two.room
+",学号:"+two.getId());//姓名:hr,年龄:16,教室:101,学号:1
Student one=new Student("gj" ,19);
System.out.println("姓名:"+one.getName()
+",年龄:"+one.getAge()+",教室:"+one.room
+",学号:"+one.getId());//姓名:gj,年龄:19,教室:101,学号:2
}
}
一旦使用static修饰成员方法,那么这就成为了静态方法,静态方法不属于对象,而是属于类的。
如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它。
如果有了static关键字,那么不需要创建对象,直接就能通过类名称来使用它。
无论是成员变量,还是成员方法。如果有了static,都推荐使用类名称进行调用。
静态变量:类名称.静态变量
静态方法:类名称.静态方法()
注意事项:
1.静态不能直接访问非静态。
原因:因为在内存当中是先有的静态内容static,后有的非静态内容。
“先人不知道后人,但是后人知道先人。”
2.静态方法当中不能用this。
原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。
package Test04;
public class MyClass {
int num;//成员变量
static int numStatic;//静态变量
//成员方法
public void method(){
System.out.println("这是一个普通的成员方法。");
//成员方法可以访问成员变量
System.out.println(num);
//成员方法可以访问静态变量
System.out.println(numStatic);
}
//静态方法
public static void methodStatic(){
System.out.println("这是一个静态方法。");
//静态方法可以访问静态变量
System.out.println(numStatic);
//静态不能直接访问非静态【重点】
// System.out.println(num); 错误写法
//静态方法中不能使用this关键字
//System.out.println(this);//错误写法
}
}
package Test04;
public class Demo02StaticMethod {
public static void main(String[] args) {
MyClass obj=new MyClass();//首先创建对象
//然后才能使用没有static关键字的内容
obj.method();
//对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名称来调用。
obj.methodStatic();//正确,不推荐,这种写法在编译之后也会被javac翻译成为类名称.静态方法名
MyClass.methodStatic();//正确,推荐
//对于本来当中的静态方法,可以省略类名称
myMethod();
Demo02StaticMethod.myMethod();//完全等效
}
public static void myMethod(){
System.out.println("自己的方法!");
}
}
package Test04;
public class Demo03StaticStudent {
public static void main(String[] args) {
//首先设置一下教室,这是静态的东西,应该通过类名称来进行调用
Student.room="101教室";
Student one=new Student("gj",20);
System.out.println("one的姓名:"+one.getName());
System.out.println("one的年龄:"+one.getAge());
System.out.println("one的教室:"+Student.room);
System.out.println("========================");
Student two=new Student("hr",18);
System.out.println("two的姓名:"+two.getName());
System.out.println("two的年龄:"+two.getAge());
System.out.println("two的教室:"+Student.room);
System.out.println("========================");
}
}
静态代码块的格式是:
public class 类名称{
static{
//静态代码块的内容}
}
}
特点:当第一次用到本类时,静态代码块执行唯一的一次。
静态内容总是优先于非静态,所以静态代码块比构造方法先执行。
静态代码块的典型用途:
用来一次性地对静态成员变量进行赋值。
package Test04;
public class Person {
static {
System.out.println("静态代码块执行!");
}
public Person(){
System.out.println("构造方法执行!");
}
}
package Test04;
public class Demo04Static {
public static void main(String[] args) {
Person one=new Person();
Person two=new Person();
}
}
java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作。
public static String toString(数组):将参数数组变成字符串(按照默认格式:[元素1,元素2,元素3])
public static void sort(数组):按照默认升序(从小到大)对数组的元素进行排序。
备注:
1.如果是数值,sort默认按照升序从小到大
2.如果是字符串,sort默认按照字母升序
3.如果是自定义的类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持。(今后学习)
题目:请使用Arrays相关的API,将一个随机字符串中的所有字符升序排列,并倒序打印。
package Test04;
import java.util.Arrays;
public class Demo02ArraysPractise {
public static void main(String[] args) {
String str="fnjdsnfjsfnjsf";
//如何进行升序排列:sort
//必须是一个数组,才能用Array.sort方法
//String---->数组,用toCharArray();
char[] chars=str.toCharArray();
Arrays.sort(chars);//对字符数组进行升序排列
//需要倒序遍历
for (int i = chars.length - 1; i >= 0; i--) {
System.out.println(chars[i]);
}
}
}
java.util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。
public static double abs(double num):获取绝对值。有多种重载。
public static double ceil(double num):向上取整。
public static double floor(double num):向下取整。
public static long round(double num):四舍五入。
Math.PI代表近似的圆周率常量(double)。
package Test04;
/*
java.util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。
*/
public class Demo03Math {
public static void main(String[] args) {
//获取绝对值
System.out.println(Math.abs(3.14));//3.14
System.out.println(Math.abs(0));//0
System.out.println(Math.abs(-2.5));//2.5
System.out.println("=====================");
//向上取整
System.out.println(Math.ceil(3.9));//4.0
System.out.println(Math.ceil(3.1));//4.0
System.out.println(Math.ceil(3.0));//3.0
//向下取整,抹零
System.out.println(Math.floor(30.1));//30.0
System.out.println(Math.floor(30.9));//30.0
//四舍五入
System.out.println(Math.round(20.4));//20
System.out.println(Math.round(10.5));//11
}
}
题目:
计算在-10.8到5.9之间,绝对值大于6或者小于2.1的整数有多少个?
分析:
1.既然已经确定了范围,for循环
2.起点位置-10.8应该转换成-10,两种办法:
2.1 可以使用Math.ceil方法,向上(向正方向)取整
2.2 强制成为int,自动舍弃所有小数位
3.每一个数字都是整数,所以步进表达式应该是num++,这样每次都是+1的。
4.如何拿到绝对值,Math.abs方法。
5.一旦发现了一个数字,需要让计数器++进行统计。
备注:如果使用Math.ceil方法,-10.8可以变成-10.0。注意double值也是可以进行++的。
package Test04;
public class Demo04MathPractise {
public static void main(String[] args) {
int count = 0;//符合要求的数量
double min = -10.8;
double max = 5.9;
//这样处理,变量i就是区间之内所有的整数
for (int i = (int) min; i < max; i++) {
int abs = Math.abs(i);//绝对值
if (abs > 6 || abs < 2.1) {
System.out.println(i);
count++;
}
}
System.out.println("总共有:" + count);//9
}
}
面向对象的三大特征:封装性、继承性、多态性。
继承是多态的前提,如果没有继承,就没有多态。
继承主要解决的问题就是:共性抽取。
在继承的关系中,“子类就是一个父类”。也就是说,子类可以被当做父类看待。
例如父类是员工,子类是讲师,那么“讲师就是一个员工”。关系:is-a。
定义父类的格式:(一个普通的类定义)
public class 父类名称{
//...
}
定义子类的格式:
public class 子类名称 extends 父类名称{
//...
}
主函数:
package Test05;
public class Demo01Extends {
public static void main(String[] args) {
//创建一个子类对象
Teacher teacher=new Teacher();
//Teacher类当中虽然什么都没写,但是会继承来自父类的method方法。
teacher.method();
//创建另一个子类助教的对象
Assistant assistant=new Assistant();
assistant.method();
}
}
父类:
package Test05;
public class Employee {
public void method(){
System.out.println("方法执行!");
}
}
两个子类(继承父类):
package Test05;
//定义了一个员工的子类:讲师
public class Teacher extends Employee {
}
package Test05;
//定义了员工的另一个子类:助教
public class Assistant extends Employee{
}
在父子类的继承关系当中,如果成员变量重名,则创建子类对象时,访问有两种方式:
直接通过子类对象访问成员变量:
等号左边是谁,就优先用谁,没有则向上找。
间接通过成员方法访问成员变量:
该方法属于谁,就优先用谁,没有则向上找。
package Test06;
public class Demo01ExtendsField {
public static void main(String[] args) {
Fu fu=new Fu();//创建父类对象
System.out.println(fu.numFu);//只能使用父类的东西,没有任何子类的内容
Zi zi=new Zi();
System.out.println(zi.numFu);//10
System.out.println(zi.numZi);//20
System.out.println("=================");
//等号左边是谁,就优先用谁
System.out.println(zi.num);//优先子类,200
//System.out.println(zi.abc);//到处都没有,编译报错!
System.out.println("=====================");
//这个方法是子类的,优先用子类的,没有再向上找
zi.methodZi();//200
//这个方法是在父类当中定义的,
zi.methodFu();//100
}
}
package Test06;
public class Fu {
int numFu=10;
int num=100;
public void methodFu(){
//使用的是本类当中的,不会向下找子类的
System.out.println(num);
}
}
package Test06;
public class Zi extends Fu{
int numZi=20;
int num=200;
public void methodZi() {
//因为本类当中有num,所以这里用的是本类的num
System.out.println(num);
}
}
package Test08;
/*
在父子类的继承关系当中,创建子类对象,访问成员方法的规则:
创建的对象是谁,就优先用谁如果没有则向上找。
注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的。
重写(Override)
概念:在继承关系当中,方法的名称一样,参数列表也一样。
重写(Override):方法的名称一样,参数列表【也一样】。覆盖、覆写。
重载(Overload):方法的名称一样,参数列表【不一样】。
方法的覆盖重写特点:创建的是子类对象,则优先用子类方法。
*/
public class Demo01ExtendsMethod {
public static void main(String[] args) {
Zi zi=new Zi();
zi.methodFu();
zi.methodZi();
//创建的是new了子类对象,所以优先用子类方法。
zi.method();
}
}
package Test09;
/*方法覆盖重写的注意事项:
1.必须保证父子类之间方法的名称相同,参数列表也相同。
@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。
这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。
2.子类方法的返回值必须【小于等于】父类方法的返回值范围。
前提:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。
3.子类方法的权限必须【大于等于】父类方法的权限修饰符。
小扩展提示:public>protected>(default)>private
备注:(default)不是关键字default,而是什么都不写,留空。
*/
public class Demo01Override {
private int num;
}
package Test09;
public class Fu {
public Object method(){
return null;
}
}
package Test09;
public class Zi extends Fu{
@Override
public String method() {
return null;
}
}
package Test11;
/*
继承关系中,父子类构造方法的访问特点:
1.子类构造方法当中有一个默认隐含的"super()"调用,所以一定是先调用的父类构造,后执行的子类构造。
2.子类构造可以通过super关键字来调用父类重载构造。
3.super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
总结:
子类必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。
*/
public class Demo01Constructor {
public static void main(String[] args) {
Zi zi=new Zi();
}
}
package Test11;
public class Fu {
public Fu(){
System.out.println("父类无参构造");
}
public Fu(int num ){
System.out.println("父类有参构造");
}
}
package Test11;
public class Zi extends Fu {
public Zi(){
//super();//调用父类无参构造方法
super(20);//在调用父类重载的构造方法
System.out.println("子类构造方法");
}
}
=========================================================================
package Test12;
public class Fu {
int num=10;
public void method(){
System.out.println("父类方法");
}
}
package Test12;
/*
super关键字的用法有三种:
1.在子类的成员方法中,访问父类的成员变量。
2.在子类的成员方法中,访问父类的成员方法。
3.在子类的构造方法中,访问父类的构造方法。
*/
public class Zi extends Fu{
int num=20;
public Zi(){
super();
}
public void methodZi(){
System.out.println(super.num);//父类中的num
}
public void method(){
super.method();//访问父类中的method
System.out.println("子类方法");
}
}
=========================================================================
package Test12;
public class Fu {
int num=10;
public void method(){
System.out.println("父类方法");
}
}
package Test12;
/*
super关键字用来访问父类内容,而this关键字用来访问本类内容。用法也有三种:
1.在本类的成员方法中,访问本类的成员变量。
2.在本类的成员方法中,访问本类的另一个成员方法。
3.在本类的构造方法中,访问本类的另一个构造方法。
在第三种用法当中要注意:
A. this(...)调用也必须是构造方法的第一个语句,唯一一个。
B.super和this两种构造调用,不能同时使用。
*/
public class Zi extends Fu{
int num=20;
public Zi(){
// super(); // 这一行不再赠送
this(123); //本类的无参构造,调用本类的有参构造
// this(1,2); //错误写法!
}
public Zi(int n){
this(1,2);
}
public Zi(int n,int m){
}
public void showNum(){
int num=10;
System.out.println(num);//局部变量
System.out.println(this.num);//本类中的成员变量
System.out.println(super.num);//父类中的成员变量
}
public void methodA() {
System.out.println("AAA");
}
public void methodB() {
System.out.println("BBB");
}
}
=========================================================================
返回看P163。
=========================================================================
Java语言是单继承的。
一个类的直接父类只能有唯一一个。
class A{}
class B extends A{}//正确
class C{}
class D extends A,C{}//错误
=========================================================================
package Test13;
public class DemoMain {
public static void main(String[] args) {
// Animal animal=new Animal();//错误写法!不能直接创建类对象
Cat cat=new Cat();
cat.eat();
}
}
package Test13;
/*
抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。
抽象类:抽象方法所在的类,必须是抽象类才行。在class之前写上abstract即可。
如何使用抽象类和抽象方法:
1.不能直接创建new抽象类对象。
2.必须用一个子类来继承抽象父类。
3.子类必须覆盖重写抽象父类当中所有的抽象方法,
覆盖重写(实现):子类去掉抽象方法的abstract关键字,然后补上方法体大括号。
4.创建子类对象进行使用。
*/
public abstract class Animal {
//这是一个抽象方法,代表吃东西,但是具体吃什么(大括号的内容)不确定。
public abstract void eat();
//这是普通的成员方法
public void normalMethod(){
}
}
package Test13;
public class Cat extends Animal {
@Override
public void eat(){
System.out.println("猫吃鱼");
}
}
package Test14;
public class DemoMain {
public static void main(String[] args) {
Zi zi=new Zi();
zi.eat();
}
}
package Test14;
/*
一个抽象类不一定含有抽象方法。
只要保证抽象方法所在的类是抽象类,即可。
这样没有抽象方法的抽象类,也不能直接创建对象,在一些特殊场景下有用途。
*/
public abstract class MyAbstract {
}
package Test14;
public abstract class Fu {
public Fu(){
System.out.println("抽象父类构造方法执行!");
}
public abstract void eat();
}
package Test14;
public class Zi extends Fu{
public Zi(){
//super();
System.out.println("子类构造方法执行");
}
@Override
public void eat() {
System.out.println("吃饭");
}
}
============================================================================================================================================
package Test15;
public class DemoMain {
public static void main(String[] args) {
// Animal animal=new Animal(); //错误!
// Dog dog=new Dog();//错误,这也是抽象类
Dog2Ha ha=new Dog2Ha();//这是普通类,可以直接new对象。
ha.eat();
ha.sleep();
System.out.println("=====================");
DogGolden golden =new DogGolden();
golden.eat();
golden.sleep();
}
}
package Test15;
//最高的抽象父类
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
package Test15;
//子类也是一个抽象类
public abstract class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗吃骨头");
}
//public abstract void sleep();
}
package Test15;
public class Dog2Ha extends Dog{
@Override
public void sleep(){
System.out.println("呵呵呵...");
}
}
package Test15;
public class DogGolden extends Dog{
@Override
public void sleep(){
System.out.println("呼呼呼...");
}
}
package Test16;
import java.util.ArrayList;
public class MainRedPacket {
public static void main(String[] args) {
Manager manager=new Manager("群主",100);
Member one=new Member("成员A",0);
Member two=new Member("成员B",0);
Member three=new Member("成员c",0);
manager.show();//100
one.show();//0
two.show();//0
three.show();//0
System.out.println("==============================");
//群主总共发20块钱,分成3个红包
ArrayList<Integer> redList=manager.send(20,3);
//三个普通成员收红包
one.receive(redList);
two.receive(redList);
three.receive(redList);
manager.show();//100-20=80
//6、6、8,随机分给三个人
one.show();
two.show();
three.show();
}
}
package Test16;
public class User {
private String name;//姓名
private int money;//余额,当前用户拥有的钱数
public User() {
}
public User(String name, int money) {
this.name = name;
this.money = money;
}
//展示一下当前用户有多少钱
public void show(){
System.out.println("我叫:"+name+",我有多少钱:"+money);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
package Test16;
import java.util.ArrayList;
//群主的类
public class Manager extends User {
public Manager(){
}
public Manager(String name,int money){
super(name,money);
}
public ArrayList<Integer> send(int totalMoney,int count){
//首先需要一个集合,用来存储若干个红包的余额
ArrayList<Integer> redList=new ArrayList<>();
//首先看一下群主自己有多少钱
int leftMoney=super.getMoney();//群主当前余额
if(totalMoney>leftMoney){
System.out.println("余额不足");
return redList;//返回空集合
}
//扣钱,其实就是重新设置余额
super.setMoney(leftMoney-totalMoney);
//发红包需要平均拆分成count份
int avg=totalMoney/count;
int mod=totalMoney % count;//余数,也就是甩下的零头
//除不开的零头,包在最后一个红包当中
//下面把红包一个一个放到集合当中
for (int i = 0; i < count-1; i++) {
redList.add(avg);
}
//最后一个红包
int last=avg+mod;
redList.add(last);
return redList;
}
}
package Test16;
import java.util.ArrayList;
import java.util.Random;
//普通成员
public class Member extends User{
public Member() {
}
public Member(String name, int money) {
super(name, money);
}
public void receive(ArrayList<Integer>list){
//从多个红包当中随便抽取一个,给我自己。
//随机获取一个集合当中的索引编号
int index=new Random().nextInt(list.size());
//根据索引,从集合当汇总删除,并且得到被删除的红包,给我自己
int delta = list.remove(index);
//当前成员自己本来有多少钱:
int money=super.getMoney();
//加法,并且重新设置回去
super.setMoney(money+delta);
}
}
=========================================================================
接口就是一种公共规范标准。
只要符合规范标准,就可以大家通用。
=============================
接口就是多个类的公共规范。
接口是一种引用数据类型,最重要的内容就是其中的:抽象方法。
如何定义一个接口的格式:
public interface 接口名称{
//接口内容
}
备注:换成了关键字interface之后,编译生成的字节码文件仍然是:.java-->.class。
如果是Java 7,那么接口中可以包含的内容有:
1.常量
2.抽象方法
如果是Java 8,还可以额外包含有:
3.默认方法
4.静态方法
如果是Java 9,还可以额外包含有:
5.私有方法
<<<<<<接口里面的方法只能是抽象方法,默认的规则。
就像是构造方法写不写都会有一个默认的空构造>>>>>>>>>>>>>>>>>>>>>>>>>>>>
接口使用步骤:
1.接口不能直接使用,必须有一个“实现类”来“实现”该接口。
格式:
public class 实现类名称 implements 接口名称{
//...
}
2.接口的实现类必须覆盖重写(实现)接口中所有的抽象方法。
实现:去掉abstract关键字,加上方法体大括号。
3.创建实现类的对象,进行使用。
package Test17;
public class Demo01Interface {
public static void main(String[] args) {
//错误写法@!不能直接new接口对象使用。
// MyInterfaceAbstract inter=new MyInterfaceAbstractImpl()
//创建类的对象使用
MyInterfaceAbstractImpl impl=new MyInterfaceAbstractImpl();
impl.methodAbs1();
impl.methodAbs2();
impl.methodAbs3();
impl.methodAbs4();
}
}
package Test17;
/*
在任何版本的Java中,接口都能定义抽象方法。
格式:
public abstract 返回值;类型 方法名称(参数列表);
注意事项:
1.接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
2.这两个关键字修饰符,可以选择性忽略。(今天刚学,不推荐。)
3.方法的三要素,可以随意定义。
*/
public interface MyInterfaceAbstract {
//这是一个抽象方法
public abstract void methodAbs1();
//这也是抽象方法
abstract void methodAbs2();
//这也是抽象方法
public void methodAbs3();
//这也是抽象方法
void methodAbs4();
}
package Test17;
public class MyInterfaceAbstractImpl implements MyInterfaceAbstract{
@Override
public void methodAbs1() {
System.out.println("这是第一个方法!");
}
@Override
public void methodAbs2() {
System.out.println("这是第二个方法!");
}
@Override
public void methodAbs3() {
System.out.println("这是第三个方法!");
}
@Override
public void methodAbs4() {
System.out.println("这是第四个方法!");
}
}