💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
函数与类前面的修饰符示例
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
控制结构示例
包含的内容有:for循环、while循环、switch语句,if语句
public static void main(String[] args) {
int a=0;
for (int i = 0; i <10 ; i++) {
a+=1;
}
while (a>0){
if(a%2==0){
System.out.println(a+"是偶数");
}
else{
System.out.println(a+"是奇数");
}
a-=1;
}
switch(a){
case 0:
System.out.println("a是"+0);
break;
case 1:
System.out.println("a是"+1);
break;
}
}
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
主数据类型与引用
primitive主数据类型+引用=变量
primitive的八种主数据类型
类型 | 位数 | 值域 |
---|---|---|
boolean | JVM决定 | true或false |
char | 16 bits | 0~65535 |
byte | 8 bits | -128~127 |
short | 16 bits | -32768~32767 |
int | 32 bits | ±2147483648 |
long | 64 bits | - 很大 ~ + 很大 |
float | 32 bits | 范围规模可变 |
double | 64 bits | 范围规模可变 |
注意,整数默认为int类型,小数默认为double类型,在创建其他类型变量以及运算时要标明。
float a=1.5f;//这个f不写则1.5默认为double,然后由double转为float
当大杯转小杯时可能会导致数据溢出,因此要注意数据的范围,以此来选择数据类型。
当编译器无法识别能否进行数据转化时,需要进行强制转换。
public class test {
public static void main(String[] args) {
long a=123;
//int b=a;会报错,编译不通过
int b=(int) a;
System.out.println(a);
}
}
自动强制转换的规则:
引用reference
如果一个变量是类类型,而非基本类型,那么该变量又叫引用。
可以把实例化的对象的reference当做一个遥控器,远程遥控其他的行为。
当实例化一个对象的时候,会创建一个遥控器,遥控器在栈区,对象在堆区。
Book b=new Book();//new Book();只是创建一个对象,前面的b表示引用指向他,等号表示指向
Book c=new Book();
Book d=c;//这时候c和d两个遥控器遥控一个对象
c=b;//这时候c和b遥控同一个对象,但是d仍然遥控自己的那个对象
作用域
- 声明在类的外面,变量就叫做字段 或者属性、成员变量、Field ,其作用域就是从其声明的位置开始的整个类
- 变量是参数:作用域在方法中
- 方法的局部变量:在方法中创建的变量作用域在方法内部
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
运算符
逻辑运算符
运算符 | 描述 |
---|---|
&& | 与 |
|| | 或 |
!= | 不等于 |
! | 非 |
-
短运算符
比如&&,当两端都为真才得到真,当左边为假便不会再计算右边
-
长运算符
比如&,强制虚拟机必须做两端的操作
算数运算符
符号 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取余 |
++ | 自增 |
– | 自减 |
关系操作符
符号 | 描述 |
---|---|
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
== | 是否相等 |
!= | 不等于 |
位运算符
参见ACM——位运算符整理
用的不多,用来提高运算速度,可以忽略不学。
赋值运算符
符号 | 描述 |
---|---|
+= | a=a+x |
-= | a=a-x |
*= | a=a*x |
/= | a=a/x |
%= | a=a%x |
&= | a=a&x |
|= | a=a|x |
^= | a=a^x |
>>= | a=a>>x |
<<= | a=a<<x |
三元操作符
(判断)?A:B;
当判断的内容为真时返回A,否则返回B
int k = i < j ? 99 : 88;
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
数组
创建与初始化数组
数组是一个固定长度,包含相同类型数据的容器,具有默认值
public class demo extends test{
public static void main(String[] args) {
int []a=new int[5];//或者是写int a[]=new int[5];
int []b = new int[]{100,102,444,836,3236};
a[0]=15;
System.out.println(a[0]);
System.out.println(a.length);
}
}
复制数组与合并数组
或者使用Arrays类的方法,或者是
复制数组: System.arraycopy(src, srcPos, dest, destPos, length)
- src: 源数组
- srcPos: 从源数组复制数据的起始位置
- dest: 目标数组
- destPos: 复制到目标数组的起始位置
- length: 复制的长度
public static void main(String[] args) {
int a [] = new int[]{18,62,68,82,65,9};
int b[] = new int[3];//分配了长度是3的空间,但是没有赋值
//通过数组赋值把,a数组的前3位赋值到b数组
System.arraycopy(a, 0, b, 0, 3);
//把内容打印出来
for (int i:b) {
System.out.print(b[i] + " ");
}
}
初始化二维数组与不规则长度数组
public static void main(String[] args) {
//初始化二维数组,
int[][] a = new int[2][3]; //有两个一维数组,每个一维数组的长度是3
a[1][2] = 5; //可以直接访问一维数组,因为已经分配了空间
//只分配了二维数组
int[][] b = new int[2][]; //有两个一维数组,每个一维数组的长度暂未分配
b[0] =new int[3]; //必须事先分配长度,才可以访问
b[0][2] = 5;
//指定内容的同时,分配空间
int[][] c = new int[][]{{1,2,4}, {4,5}, {6,7,8,9}};
}
增强for循环
格式:可以通过values.for
快捷键实现
for (int each : values) {
System.out.println(each);//do something
}
Arrays类的常用方法
包:import java.util.Arrays;
常用方法:
方法 | 描述 | 作用 |
---|---|---|
int[] b = Arrays.copyOfRange(a, 0, 3); | a是原数组,0取的到,3取不到 | 数组复制 |
String content = Arrays.toString(a); | a是数组,得到[18, 62, 68, 82, 65, 9] | 转换为字符串 |
Arrays.sort(a); | a是数组 | 升序排序 |
Arrays.binarySearch(a, 62 ): | 62是要搜索的元素 | 搜索,前提是升序排列了,不存在返回负数 |
Arrays.equals(a, b) | ab为两个数组 | 判断两个数组是否相同 |
Arrays.fill(a, 5 ); | 填充a数组全为5 | 填充(初始化) |
创建类的数组
Dog[] myDogs=new Dog[3];
myDogs[0]=new Dog();//放咖啡的杯子就只能放咖啡
myDogs[0].name="Fido";
myDogs[0].bark();
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
初识类与对象——基本概念
封装数据
在创建数据时,标明private,否则实例化的对象可以直接修改对应的值,把内裤给别人看了就挺尴尬的…
可以创建对应的方法来获取或者设置相应数据,比如
public void setname(String newname){
name=newname+getname();
}
实例变量的默认值
当你仅仅只是声明一个变量,但是不初始化的时候,java会默认给你赋一个值
数据类型 | 默认值 |
---|---|
integers | 0 |
floating points | 0.0 |
boolean | false |
references | null |
实例变量与局部变量的差别
实例变量是声明在类里面的,局部变量是声明在类的方法里的,局部变量在使用前必须要先赋值,否则编译器会报错。
可变长参数
在参数位置加三个点,例如
public void attack(Hero ... heros){
for (Hero:heros) {
//do something
}
}
//传参时参数用逗号隔开
构造函数
声明为public,构造函数可以重载哦,注意别写void ,否则就成了普通方法
class demo {
public demo(String a){
System.out.println("调用了构造函数参数是"+a);
}
public demo(){
System.out.println("调用了默认构造");
}
public static void main(String[] args) {
demo test1=new demo("草");
demo test2=new demo();
}
}
this关键字
指向当前类本身的元素,类似c++,即使是同名的,this.name=name;
也可以赋值,称为隐式调用。
但是只要和属性不同名,直接赋值也OK的,this还能实现构造方法
的相互调用
一个包(package)内的class可以互相访问
要访问别的class用import导入哦,import package.class
成员变量四种权限修饰符
标黄了就表示不能访问到,不写默认为protected
自身 | 同包子类 | 不同包子类 | 同包类 | 其他类 | |
---|---|---|---|---|---|
private | 访问 | 继承 | 继承 | 访问 | 访问 |
protected | 访问 | 继承 | 继承 | 访问 | 访问 |
public | 访问 | 继承 | 继承 | 访问 | 访问 |
package | 访问 | 继承 | 继承 | 访问 | 访问 |
属性初始化
对象属性初始化有3种
- 声明该属性的时候初始化 public String name =
"some hero"
; - 构造方法中初始化
- 使用set方法
- 初始化块===>大括号括起来,不常用,别几把了解了
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
类的封装
封装概述
封装是面向对象三大特征之一(封装、继承、多态),是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的
封装原则
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作与访问,成员变量设置为private
,提供对应的getAbb
和setAbb
方法
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
类的继承
子类继承父类可以获得父类的属性和方法,一个父类可以被多个子类继承,但是一个子类只能继承一个父类,不过一个类可以实现多个接口,Object类是所有类的父类,类的继承关键字是extents
继承中变量访问顺序
在子类方法中寻找一个变量时如下顺序:
- 子类局部范围找
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲)
继承中构造方法的访问顺序
子类中的所有构造方法都会默认先访问父类的无参构造方法
,子类会继承父类的数据,因此在子类初始化前一定要先进行父类初始化,每一个子类第一句话默认都是super()
继承中成员方法的访问顺序
顺序如下:先当前再长远
- 子类成员范围找
- 父类成员范围找
- 如果都没有就报错(不考虑父亲的父亲)
super关键字
- 调用父类带参构造方法
实例化子类的时候,会先调用父类的构造方法,当多个构造方法时,默认调用父类无参构造方法
如果想调用父类带参构造,需要用super,例如
super(name);//在ADHero带参构造下写,这个相当于调用参数为name的父类构造方法
- 调用父类属性
super.speed;//父类的属性
- 调用父类的方法
super.useItem();//父类的方法
this与supper的区别
this是访问或调用本类的成员变量或方法,supper是操作父类的
类的初始化顺序
静态变量与静态初始块只会初始化一次,但是类成员变量在每次初始化都会进行初始化,而且是先进行成员变量的初始化再调用构造函数
父类静态变量 > 父类静态初始块 > 子类静态变量 > 子类静态初始块 > 父类成员变量 > 父类非静态初始块 > 父类构造器 > 子类成员变量 > 子类非静态初始块 > 子类构造器
方法(重写)覆盖
当子类需要父类的功能,而功能主题子类有自己特有内容时,可以重写父类的方法,这样既沿袭了父类的功能,又定义了子类独有的内容。如果在子类中定义一个方法,其名称、返回类型及参数签名正好与父类中某个方法的名称、返回类型及参数签名相匹配,就说子类的方法覆盖了父类的方法。简单来说,子类的方法和父类一模一样
就说覆盖,注解是@Override
四个特点:
- 有继承关系的两个类
- 具有相同方法名、返回值类型、形式参数列表
- 子类访问权限不能更低
- 抛出异常不能更多
四个注意事项:(多态语法)
- 方法覆盖只是针对于方法,和属性无关。
- 私有方法无法覆盖
- 构造方法不能被继承,所以构造方法也不能被覆盖。
- 方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
类的多态
多态是同一对象在不同时刻表现出来的不同形态
多态的形式:
- 具体类多态
- 抽象类多态
- 接口多态
多态的前提和体现:
- 有继承/实现关系
- 有方法重写
- 有父类(接口)引用指向子(实现)类对象
操作符的多态:
- 加号两边都是数字代表数字相加
- 加号两边有一个字符串则表示字符串拼接
类的多态:
- 子类父类转型
/**
LifePotion(血瓶)和MagicPotion(魔瓶)都继承于Item,当使用effect方法时只需要传入Item对象即可,
不用再写useLifePotion和useMagicPotion两个方法
*/
public class Hero {
public String name;
protected float hp;
public void useItem(Item i){
i.effect();
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
LifePotion lp =new LifePotion();
MagicPotion mp =new MagicPotion();
garen.useItem(lp);
garen.useItem(mp);
}
}
多态的好处与弊端
多态的优点:
- 提高了程序的扩展性
多态的弊端:
- 不能使用子类的特有功能
多态中转型
instanceof判断引用是否指向对象
子类转父类,向上:ADHero引用转Hero引用是完全没问题的
父类转子类,向下:需要用到子类的类名进行强制转化,为什么要加呢,因为不知道子类的引用指向的对象是谁,
注:父类转子类之后再转子类可能会报错
多态转换的顺序
https://www.bilibili.com/video/BV18J411W7cE?p=173
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
抽象类(abstruct)
介绍
只对方法进行声明,而不去实现,在java中,一个没有方法体的方法称为抽象方法,如果类中有抽象方法,该类必须定义为抽象类
抽象类以及子类的特点
- 抽象类和抽象方法必须使用
abstruct
进行修饰 - 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类不能实例化,但是可以通过子类对象实例化,这叫抽象类的多态
- 抽象类的子类要么重写抽象类中所有的抽象方法,要么是抽象类
- 抽象是多态的表现形式之一
抽象类的成员特点
- 抽象类不能被实例化
- 成员变量既可以是变量也可以是常量(final)
- 构造方法可以有,作用是子类访问父类进行数据的初始化
- 成员方法可以是抽象的也可以是非抽象的,非抽象的方法提高了代码的复用性
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
抽象类名作为形参和返回值
- 方法形参是抽象类名时,其实需要的是
该抽象类的子类对象
- 方法返回值是抽象类名时,其实返回的时
该抽象类的子类对象
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
接口(interface)
介绍
接口就像一种公共规范,只要符合规范标准,大家就可以通用。Java中的接口更多体现在对行为的抽象
接口的特点
- 接口用
interface
修饰 - 类实现接口用
implements
表示 - 接口不能实例化
- 接口是多态的表现形式之一
接口的成员特点
-
成员变量只能是常量,默认修饰符:
public static final
-
接口没有构造方法,因为接口更多的是体现在对行为的抽象
-
成员方法只能是抽象方法
,默认修饰符:public abstruct
-
JDK8之后接口都有了默认实现,可以在实现的类中直接调用
设计接口
接口就像约定,接口定义某些方法,交给某个类去实现,一个类可以实现多个接口 用逗号隔开就行
接口定义关键字:interface
public interface AD{
public void physicAttack();
}
类去实现接口的关键字:implements
public class ADHero extends Hero implements AD{
public void physicAttack(){
System.out.println("发起进攻");
}
}
注意,假如类不实现接口约定的方法,这个类会报错。
类和接口的关系
- 类和类的关系:继承关系,只能是单继承,但是可以多层继承
- 类和接口的关系:实现关系,类去实现接口,可以单实现,也可以多实现
- 接口和接口的关系:继承关系,可以单继承也可以多继承
注:可以继承一个类时同时实现多个接口
抽象类与接口的区别
# 成员区别
抽象类---->常量和变量,可以定义四种访问权限,有构造方法,有抽象方法,也有非抽象方法
接口------>只有公共的静态的常量和抽象方法
# 关系区别
抽象类---->只能被单继承
接口------>可以被类多实现(被其他接口多继承)
# 设计理念区别
抽象类---->抽象类是对类抽象,是对根源的抽象,包括属性和行为,抽象类反映的是is-a关系,表示这个对象是什么
接口------>主要是对行为动作的抽象,接口反映的是like-a关系,表示这个对象能做什么,接口是更加纯粹的抽象。
注:最大的相同点是抽象类和接口都不能直接实例化
接口名作为形参和返回值
- 方法的形参是接口名,其实需要的是
该接口的实现类对象
- 方法的返回值是接口名,其实需要的是
该接口的实现类对象
默认方法(Java8)
例如我们想升级接口,但是如果升级的话所有的实现类都需要实现这个新方法,可以使用一个新接口继承这个接口,然后找类去实现它,但是太麻烦了,于是有了默认实现方法
public interface Test{
public default void show() {//public可以省略,但是default不行
System.out.println("默认方法执行了,冲!");
}
}
静态方法(Java8)
静态方法只能被接口调用,这样做的目的是防止实现多个接口的时候,这多个接口存在同一个静态方法,导致混乱
public interface Test{
public static void show() {
System.out.println("静态方法执行了,冲!");
}
}
public class TestInterface{
public void main(String[] args) {
Test.show();
}
}
私有方法(Java9)
Java 9中新增了带方法体的私有方法,这其实在Java8中就埋下了伏笔:Java8允许在接口中定义带方法体的默认方法和静态方法。这样可能就会引发一个问题:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法
,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java9增加私有方法的必然性
定义的格式:
- 格式一:
private 返回值类型 方法名(参数列表)
- 格式二:
private static 返回值类型 方法名(参数列表)
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
Java中的内部类
内部类介绍
内部类就是在类中定义一个类,例如在类A中定义了类B,这个类B就是内部类,
按照内部类在类中定义的位置不同,可以分为两种形式:
- 在类的成员位置:成员内部类,定义在类中
- 在类的局部位置:局部位置类,定义在类方法中
内部类的定义格式如下:
public class ClassNameA{
修饰符 class ClassNameB{
}
}
内部类:java文件的class里面的类,属性和方法平等的位置
内部类与外部类的访问特点
- 内部类可以直接访问外部类的所有属性和方法
- 外部类如果想访问内部类成员必须先创建对象
成员内部类
如何访问内部类呢?
外部类名.内部类名 对象名 = 外部类名.内部类名
通常情况下,我们把类做成内部类的目的就是不让别人访问到,因此通常是将内部类修饰为private
,外部类定义一个方法去调用内部类的函数,我们只需要调用外部对象的该方法即可
局部内部类
如果想调用局部内部类只能是在方法中创建内部类对象,然后使用内部类对象去访问方法
public class Test {
public int num = 10;
public void method() {
class Inner {
public void show(){
System.out.println(num);
}
}
Inner inner = new Inner();
inner.show();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
非静态内部类
通过new 外部类().new 内部类()
的形式去使用
Hero garen = new Hero();
BattleScore score = garen.new BattleScore();
静态内部类
static修饰,就不用再创建外部类
Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
匿名内部类(是局部内部类一种)
前提是存在一个类,这个类可以是具体类也可以是抽象类,格式如下:
xxxx = new ClassNameOrInterfaceName(){
//重写方法
}
Hero是一个抽象类(abstruct),重写方法表示继承了这个类或实现了这个接口
Hero hero = new Hero(){
//实现一个attack新方法
public void attack() {
System.out.println("新的进攻手段");
}
};
hero.attack();
///--------也可以------//
new Hero(){
//实现一个attack新方法
public void attack() {
System.out.println("新的进攻手段");
}
}.attack();
匿名内部类的本质是继承了该类或实现了该接口的匿名对象
内部类与匿名类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置
本地类
本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
//与匿名类的区别在于,本地类有了自定义的类名
class SomeHero extends Hero{
public void attack() {
System.out.println( name+ " 新的进攻手段");
}
}
SomeHero h =new SomeHero();
h.name ="地卜师";
h.attack();
}
}
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
基本类型的包装类
基本数据类型与包装类对应关系
基本类型转封装类
//一个int类型数据
int i = 5;
//基本类型转换成封装类型
Integer it = new Integer(i);
封装类转基本类型
//一个封装类型
Integer it = new Integer(5);
//封装类型转换成基本类型
int i2 = it.intValue();
自动装箱
基本数据类型通过等号转换为包装类,称为装箱
int i = 5;
//自动装箱为Integer类型
Integer it2 = i;
自动拆箱
包装类通过等号转为基本数据类型,称为拆箱
Integer it = new Integer(5);
//自动拆箱为int基本数据类型
int i3 = it;
int的最大值最小值
//int的最大值
System.out.println(Integer.MAX_VALUE);
//int的最小值
System.out.println(Integer.MIN_VALUE);
字符串与数值相互转换
-
数字–>字符串(第二种方式不介绍了)
String str = String.valueOf(5); //或者是String str = 5+"";
-
字符串–>数字
int i= Integer.parseInt("15");
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
String类
格式化输出
- %s 表示字符串
- %d 表示数字
- %n 表示换行
printf和format能够达到一模一样的效果,如何通过eclipse查看java源代码 可以看到,在printf中直接调用了format
String sentenceFormat ="%s 在进行了连续 %d 次击杀后,获得了 %s 的称号%n";
System.out.printf(sentenceFormat,name,kill,title);
字符与Character工具类
char用来保存一个字符,char对应的封装类是Character
public class TestChar {
public static void main(String[] args) {
System.out.println(Character.isLetter('a'));//判断是否为字母
System.out.println(Character.isDigit('a')); //判断是否为数字
System.out.println(Character.isWhitespace(' ')); //是否是空白
System.out.println(Character.isUpperCase('a')); //是否是大写
System.out.println(Character.isLowerCase('a')); //是否是小写
System.out.println(Character.toUpperCase('a')); //转换为大写
System.out.println(Character.toLowerCase('A')); //转换为小写
String a = 'a'; //不能够直接把一个字符转换成字符串
String a2 = Character.toString('a'); //转换为字符串
}
}
字符串操作
charAt | 获取字符 |
---|---|
toCharArray | 获取对应的字符数组 |
subString | 截取子字符串 |
split | 分隔 |
trim | 去掉首尾空格 |
toLowerCase toUpperCase | 大小写 |
indexOf lastIndexOf contains | 定位 |
replaceAll replaceFirst | 替换 |
startsWith | 以…开始 |
endsWith | 以…结束 |
equals | 判断是否相等 |
equalsIgnoreCase | 忽略大小写判断是否相等 |
StringBuffer
package character;
public class TestString {
public static void main(String[] args) {
String str1 = "let there ";
StringBuffer sb = new StringBuffer(str1); //根据str1创建一个StringBuffer对象
sb.append("be light"); //在最后追加
System.out.println(sb);
sb.delete(4, 10);//删除4-10之间的字符,都是闭区间
System.out.println(sb);
sb.insert(4, "there ");//在4这个位置插入 there
System.out.println(sb);
sb.reverse(); //反转
System.out.println(sb);
}
}
StringBuffer与StringBuilder的区别是:StringBuilder是线程安全的
Random类
方法 | 描述 |
---|---|
Random random = new Random(10); | 10是seed,可以不写 |
random.nextInt(10) | 随机在最小int~最大int取一个数 |
random.nextInt(10) | [0,x)的随机整数,x不能小于0 |
nextFloat() | 随机一个float |
nextDouble() | 随机一个Double |
nextLong() | 随机一个Long |
nextBoolean() | 随机true或false |
nextBytes(byte[] bytes) | 为一个byte类型的数组随机赋值 |
nextGaussian() | 随机生成一个高斯分布的浮点数 |
Math类
方法 | 描述 |
---|---|
Math.abs() | 取绝对值 |
Math.ceil() | 向上取整 |
Math.floor() | 向下取整 |
Math.round(float a) | 四舍五入取整 |
Math.max(int a,int b) | 去较大的值 |
Math.min(int a,int b) | 去较小的值 |
Math.pow(double a,double b) | a的b次幂 |
Math.random() | 返回一个[0.0,1.0)之间的double值 |
System类
方法 | 描述 |
---|---|
System.currentTimeMillis() | 获取系统当前毫秒值 |
System.exit(0); | 结束正在运行的Java程序 |
System.gc(); | 垃圾回收器 |
System.getProperties() | 确定当前的系统属性 |
System.arraycopy(src, 2, dest, 0, 2); | 复制数组 |
日期类
注意:是java.util.Date;
而非 java.sql.Date,此类是给数据库访问的时候使用的
时间原点概念
零这个数字,就代表Java中的时间原点,其对应的日期是1970年1月1日 8点0分0秒 ,
为什么对应1970年呢? 因为1969年发布了第一个 UNIX 版本:AT&T,综合考虑,当时就把1970年当做了时间原点。
所有的日期,都是以为这个0点为基准,每过一毫秒,就+1。
创建日期对象
// 当前时间
Date d1 = new Date();
System.out.println(d1);
// 从1970年1月1日 早上8点0分0秒 开始经历的毫秒数
Date d2 = new Date(5000);
System.out.println(d2);
Date().gettime()获取时间戳
返回long型的时间戳,直接打印对象,会看到 “Tue Jan 05 09:51:48 CST 2016” 这样的格式,可读性比较差,可以进行日期格式化
注:System.currentTimeMillis()
也可以达到gettime()的功能,而且更精确
日期的格式化
- y 代表年
- M 代表月
- d 代表日
- H 代表24进制的小时
- h 代表12进制的小时
- m 代表分钟
- s 代表秒
- S 代表毫秒
package date;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
Date d= new Date();
String str = sdf.format(d);
System.out.println("当前时间通过 yyyy-MM-dd HH:mm:ss SSS 格式化后的输出: "+str);
}
}
日历类
日历类可以转为日期类,还能翻日历,别鸡巴学了,感觉没啥用啊
import java.util.Calendar;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//采用单例模式获取日历对象Calendar.getInstance();
Calendar c = Calendar.getInstance();
//通过日历对象得到日期对象
Date d = c.getTime();
Date d2 = new Date(0);
c.setTime(d2); //把这个日历,调成日期 : 1970.1.1 08:00:00
}
}
几个常见的关键字
static静态属性与静态方法
所有的饮用都能访问,用static修饰,到时候直接用 类+原点操作符
就能直接调用
例如Math库的Pi,math.pi
final(只能操作一次)
-
修饰类。这个类不能够被继承
-
修饰方法。这个方法不能够被重写
-
修饰基本类型变量。该变量只有一次赋值机会
-
修饰引用。表示该引用只有1次指向对象的机会
-
修饰常量。表示可以直接访问当不能修改的常量
-
如果是final修饰了引用,只是不能修改地址而已,对象的属性还是可以修改的
public static final int itemTotalNumber = 6;
abstract(抽象)
-
在类中声明一个方法,这个方法没有实现体,是一个“空”方法 ,即抽象方法。
-
一个类有抽象方法,就必须声明为抽象类。一个抽象类可以没有抽象方法。
-
抽象类不能直接实例化,只能通过子类来实例化
-
一个子类继承了抽象类就必须重写抽象方法,重写的时候就不用写abstract了
结语
预祝大家学习进步✔
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋
💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋💋