1、面向对象:
面向对象的概述:面向对象就是基于面向过程的编程思想;
面向过程:强调的是每一个功能的步骤
面向对象:强调的的对象,然后由对象去调用功能
面向对象的特点:
a.是一种更符合我们的思想习惯的思想
b.将复杂简单化
c.由执行者演变成执行者;
8
面向过程关注的是过程;
面向对象开发:就是在不断地穿件对象,使用对象和指挥对象
面向对象设计:其实就是在管理和维护对象之间的关系
面向对象的特征:
a.封装
b.继承
c.多态
类与对象:
类是java语言最基本的单位
属性:对事物的描述信息 成员变量
行为:该事物可以做什么 成员方法
类:一组相关的属性和行为的集合
对象:是该类的具体表现形式,具体存在的个体
eg:
类:学生
对象:班长
学生事物:
属性:姓名,年龄,地址,
行为:吃饭,学习,睡觉
把事物转成对应的类,
成员变量:姓名。年龄,地址
成员方法:学习,吃饭,睡觉,
成员变量:和以前常量的定义是一样的格式,但是位置不同,在类中方法外,
成员方法:和以前方法的定义是一样的格式,
类:是一组相关的属性和行为的集合
对象:是该类事物的表现形式;
手机事物:
属性(成员变量):品牌,价格,颜色
行为(成员方法):打电话,发短信,玩游戏;
如何使用成员变量:
对象名.变量名s.name
如何使用成员方法:
对象名.方法名() s.study()
每天一个day,然后复习
成员变量和局部变量的区别:
a在类中的位置不同,
成员变量:在类中方法外;
局部变量:在方法定义中或在 方法声明上;
b在内存中的位置不同
成员变量:在堆内存
成员方法:在栈内存
c生命周期不同
成员变量:随着对象的存在而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
d初始化值不同:
成员变量:有默认初始化值
局部变量:没有默认初始化的值,必须定义、赋值,然后才能使用(不赋值会报错)
注意事项:
局部变量名称可以和成员变量名称一样,在方法使用的时候,采用的是就近原则;
class Varialbe{
//这是成员变量(在类中方法外)
int num = 10;
public void show()//方法
int num1 = 120;//局部变量(在方法定义中或者方法声明上)
}
形式参数的问题:
基本类型:形式参数的改变不影响实际参数;
引用类型:形式参数的改变直接影响世界参数;
匿名对象
定义:就是没有名字的对象;
student s = new student(); //s就是对象名称;
private(私有的)使用了private后变成私有的,那么局可以限制公共访问
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式;
优点:
1、隐藏实际细节,提供公共访问方式
2、提高代码的复用性
3、提高安全性
封装原则:
a、将不需要对外提供的内容隐藏起来了;
b、把属性隐藏,提供公共访问方法对其访问
private关键字
private关键字
1、是一个权限修饰符
2、可以修饰成员(成员变量、成员方法)一般修饰变量;
3、被private修饰的成员只有在本类中才能够访问
pricvate最常见的应用:
把成员变量用private修饰
提供对应的getXxx()、setXxx()方法
一个标准案例的使用;
get和set
get:获取
set:放置
/*
封装和private的应用
把成员变量用private修饰
提高对应的getXxx()和setXxx()方法
*/
//定义学生类
class Student3{
//name
private String name ;
//age
private int age;
//名字赋值:
public void setName(String n){
name = n ;
}
//名字获取值;
public String getName(){
return name;
}
//年龄赋值:
public void setAge(int a){
age = a ;
}
//年龄获取值;
public int getAge(){
return age;
}
}
//测试类
public class StudentTest {
public static void main(String []args){
//创建一个学生类
Student3 s = new Student3();
//使用成员变量:
//被private修饰了,不能直接访问
// System.out.println(s.name +"---"+s.age);
//使用getXxx方法获取成员变量
System.out.println(s.getName()+"---"+s.getAge());
//使用setXxx方法赋值
s.setName("庄心妍");
s.setAge(27);
System.out.println(s.getName()+"---"+s.getAge());
}
}
//使用getXxx方法获取成员变量
System.out.println(s.getName()+”—-“+s.getAge());
//使用setXxx方法赋值
s.setName(“庄心妍”);
s.setAge(27);
System.out.println(s.getName()+”—-“+s.getAge());
this代表当前类的对象引用;
方法被哪个对象调用,
this就代表哪个对象;
this的使用场景:
解决局部变量隐藏成员变量;
构造方法
定义:给对象的数据进行数据初始化
格式:
1、方法名与类名相同
2、没有返回值类型,连void都没有
3、没有具体的返回值;
注意事项:
1、如果我们没有给出构造方法,那么系统将自动给出一个无参构造方法;
2、如果我们给出了构造方法,那么系统将不再提供无参构造方法了;
给成员变量赋值方法:
1、setXxx()
2、构造方法
//一个标准代码的最终版;
/*
学生类:
成员变量:
String name;
int age;
构造方法:
无参
带两个参
成员方法:
getXxx() / setXxx()
show()//输出该类所有的成员变量
给成员变量赋值
1、setXxx()
2、通过构造方法
输出成员变量的方式:
1、通过getXxx()
2、通过show()给成员变量赋值;
*/
class Student6 {
private String name;
private int age;
//构造方法
//无参构造
public Student6() {
}
//带参构造
public Student6(String name, int age) {
this.name = name;
this.age = age;
}
//getXxx()和setXxx()
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;
}
//输出所有的变量,定义show()方法
public void show(){
System.out.println(name + "---" + age );
}
}
//测试类
public class StudentTest3 {
public static void main(String []args){
//方式1
//无参构造+setXxx()
Student6 s1 = new Student6();
s1.setName("庄心妍");
s1.setAge(27);
//输出
System.out.println(s1.getName() + "---" + s1.getAge());
s1.show();
System.out.println("-------------------");
//方式2
Student6 s2 = new Student6("haiqing",30);
//输出
System.out.println(s2.getName() + "---" + s2.getAge());
s2.show();
}
}
变量什么时候定义为成员变量
如果这个变量是来描述这个类的信息,那么这个变量就应该定义为成员变量
变量的范围越小越好,应为能够及时的被回收;
import只能放在所有class文件的最上方,否则会报错
static的特点:(可以修饰成员变量和成员方法)
1.随着类的加载而加载;
2.优先于对象存在;
3.被类的所有对象共享;
如果某个成员变量是被所有对象共享,那么久应给定义为静态;
4.可以通过类名调用
注意事项:
1.在静态方法中没有this关键字;
静态是随着类的加载而加载,this是随着对象的创建而存在;
2.静态成员变量只能访问静态成员变量和成员方法;
静态方法:
成员变量:只能访问静态成员变量
成员方法:只能是静态的成员方法
非静态方法:
成员变量:可以访问静态的,也可以访问非静态的;
成员方法:可以是静态的成员方法,也可以是非静态的成员方法;
静态只能访问非静态,非静态可以访问一切
代码块:
定义:就是用{ }括起来的代码
局部代码块:局部位置,用于限制代码的生命周期,提高内存的利用率;
构造代码块:在类中的成员位置,用{ }括起来的 ,每次调用构造方法之前,都会调用构造代码块 ;作用:可以把构造方法中相同的代码放在一起,对对象进行初始化;;
静态代码块:在类中的成员位置,用{ }括起来的,只不过用static修饰,静态代码块只加载一次, 作用:一般对类进行初始化;
面试题:静态代码块,构造方法,构造代码块的执行顺序;
静态代码块 构造代码块 构造方法
注:静态代码块只执行一次,构造代码块每次调用构造方法都执行;
继承:
格式:
class FU {
}
class Zi extends FU{
}
//class 子类名 extends 父类名 {}
定义:
多分类中存下相同的属性和行为时,将这些类抽取到单独的一个类,那么多个类无需调用,只需要继承这个类即可,
单独的这个类成为父类,基类或超类,而多个类可以成为子类或者派生类;
优点:
1、提高了代码的复用性
2、提高了代码的维护性
3、让类与类之间产生了关系,是多态的提前, (即是优点,也是弊端)
类与类产生了关系 ,其实也是继承的弊端:类的耦合性增强了;
开发的原则: 低耦合,高内聚
耦合:类与类之间的关系
内聚:就是自己完成某件事情的能力;
java继承的的特点:
1、java只支持单继承,不支持多继承;
2、java支持多层继承(集成体系);
java继承的注意事项:
1、子类不能继承父类的私有成员(成员变量、成员方法)
2、子类不能访问父类的构造方法,但是可以通过super关键字访问父类构造方法
3、不要为了部分功能使用继承,
什么时候考虑继承:
继承体现的是一种关系;(子类一定是父类的一种);
假设法:如果有两个类a,b, 只要他们符合a是b的一种,或者b是a的一种,那么久可以考虑使用继承
类的组成:
成员变量:
构造方法:
成员方法:
继承中成员变量的关系
1、子类的成员变量和父类的成员变量名称不一样;
2、子类的成员变量和父类的成员变量一样;在子类方法中,
访问一个变量的查找顺序:
a.在子类方法做的局部变量查找,有就使用;
b.在子类的成员范围找,有就使用
c.在父类的成员范围找,有就使用
d.如果还找不到哦,就报错
this 和super的区别:
分别是什么:
this代表本类对应的引用
super代表父类存储空间的标识,(可以理解为父类引用,可以操作父类的引用)
使用方法:
1、调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
2、调用构造方法
this(……)调用本类的构造方法
super(……)调用父类的构造方法
3、调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中的构造方法的关系:
1、子类中所有的构造方法都会访问父类中空参数的构造方法(注:这里访问的是空参,而不是实参)
2、原因:
因为子类会继承父类的中的数据,可能还会使用父类的数据,所以子类初始化之前,一定要完成父类数据的初始化;
注意:子类每一个构造方法的第一条语句默认都是:super()。super()为空说明调用父类的无参构造;
如果父类没无参构造方法,(有带参构造方法),那么子类的构造方法会出现什么结果:
报错;
解决方案:
1、在父类加一个无参构造方法
2、通过使用super()去显示调用父类的带参构造方法;
3、子类通过this去调用本类的其他构造方法;子类一定要有一个访问父类构造方法,否则父类数据没有初始化
注意::
this(……)和super(……),必须出现在第一条语句上
如果不是放在第一条语句上面,局可能对父类数据进行多次数据初始化,所以必须放在第一句;
8.21
继承中成员变量的方法:
1、子类中的方法和父类的方法声明不一样;
2、子类中的方法和父类的方法声明一样;
通过子类调用方法:
a,先找子类,看看有没有这个方法;,有就使用
b,在看父类有没这个方法,有就使用
没有就报错
方法重载:本类中出现的方法名一样,参数列表不同的方法,与返回值无关
方法重写:子类中出现了和父类中方法声明一模一样的方法;(别称:方法覆盖、方法复写)
方法重载可以改变返回值类型吗?
可以,因为它和返回值类型没有关系;
override:方法重写
overload:方法重载
this和super关键字的区别,
this:代表当前类的对象引用
super:代表当前存储空间的标识(可以理解为父类引用,通过super可以访问父类成员)
应用场景:
成员变量:
this:.成员变量
super:成员变量
构造方法:
this(……)
super(……)
成员方法:
this.成员方法
super.成员方法
使用特点:
如果方法名不同,就有调用对应的方法
如果方法名相同,最终使用的是子类自己的。
方法重写的应用:
当子类需要父类的功能,而功能主体子类持有知己特有内容时间,可以重写父类中的方法,这样既沿袭了父类的功能,有定义了子类特有的内容;
注意事项:
1、父类的私有方法不能被重写
因为父类私有方法子类就无法继承,
2、子类重写父类方法时,访问权限不能更低;
3、父类静态方法,子类也必须通过静态方法重写;
子类重写父类方法时,最好是一模一样,
final关键字(最终的)
方法重载中,子类会把父类的方法覆盖,为了不被覆盖掉,使用final关键字
final可以修饰类、方法、变量;
class fu{
public final void show(){ //final 可以让父类的方法不会被子类覆盖
System.out.printlnl("jajajajjajaj")
}
}
特点:
final可以修饰类:被修饰过后的类,就成为最终类,不能被继承 // final class fu
final可以修饰方法:该方法不能被重写,(覆盖,复写) public final void show(){ }
final可以修饰变量:该变量不能被重新赋值,这个变量就是常量;
常量:
1、字面值常量:10、true、”hello”
2、自定义常量:final int x= 10;
面试题:
局部变量是基本数据类型:final无法为最终变量赋值
局部变量是引用数据类型:
基本类型:基本类型的值是不能把发生改变;
引用类型:引用类型的地址值不能发生改变,但是该对象的堆内存的值可以发生改变的
final修饰变量的初始化时机:
1、被final修饰的变量只能赋值一次;
2、在构造方法之前完毕之前,(非静态常量)
多态:
定义:某一个事物在不同时刻表现不同的状态
前提:
1、要有继承关系
2、要有方法重写
3、要有父类引用指向子类对象;
fu f = new zi();
多态中的成员变量访问特点:
1、成员变量:编译看左边,运行看左边;(运行其实就是看父类)
2、构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化;
3、承运方法:编译看左边,运行看右边;(运行其实就是看子类);
注意:调方法看的是父类的成员变量;
4、静态方法:编译看左边,运行看右边;
(静态和类相关,算不上重写,所以编译看左边)
由于成员方法存在重写,所以编译看右边;
多态的优点:
1、提高了代码的维护性
2、提高了代码的扩展性
多态的弊端:
1、不能使用子类特有功能。父类没有定义 的就不能而使用子类功能就会报错;
父类不能访问子类,子类可以访问父类,但是在多态中,子类不能访问父类没有的成员方法;
如果要使用子类特有功能,有什么方式
1、创建子类对象调用方法,(可以使用,但是占内存)
2、把父类的引用强制转换为子类的引用,(向下转型)
向上转型: Fu f = new ZI //把子变成父,本来是儿子,转变为父亲
向下转型: ZI z = (ZI)f; //本身外界看到的是父,但是转换为子 前提:该f必须是能够转换为Zi的
抽象类的概述:
动物(animal)不应该定义为具体的东西,而且动物中的吃、睡不应该是具体的,把一个不是具体的功能定义为抽象的功能,而一个类中有抽象的功能,那么该类必须是抽象类;
抽象类:
特点:
1、抽象类和抽象方法必须用abstract修饰,
2、抽象类中不一定有抽象方法,而有抽象方法的就一定是抽象类
3、抽象类是不能实例化的
因为他不是具体的;抽象类可以有构造方法,但是不能实例化,
构造方法的作用是:用于子类访问父类数据的初始化;
4、抽象的子类问题:
a、如果不想重写抽象方法,该子类是抽象类;
b、重写所有的抽象方法,这时候该子类是一个具体的类;
格式:
abstract class 类名 { }
public abstract void eat() //抽象方法
注意:
抽象类不一定有抽象方法,有抽象方法的就一定是抽象类;
public void show( ){ } //空方法体
public void show() //无方法;
抽象类的实例化其实就是靠具体的子类实现的,是多态的方式;
eg: animal a = new cat();
抽象类的成员特点:
成员变量:既可以是变量,也可以是常量
构造方法:用于子类访问父类数据的初始化
成员方法:既可以是抽象的,也可以是非抽象的
抽象类成员方法特性:
1、抽象方法:强制要求子类做的事情
2、非抽象方法:子类继承的事情,提高代码的复用性;
//基础班学员类
class BasicsStudent extends Student{
public BasicsStudent (){} // 无参构造
public BasicsStudent(String name ,int age ,String grand){//带参构造
super(name,age,grand);
}
public void study(){ //方法
System.out.println("基础班学习的是javaSE");
}
}
/*
学生案例:
具体事物:基础班学员,就业班学员
共性:姓名,年龄,班级,学习,吃饭
分析:
基础班学员:
成员变量:姓名,年龄,班级
构造方法:无参构造,带参构造
成员方法:学习,吃饭
就业班学员:
成员变量:姓名,年龄:班级;
构造方法:无参构造,带参构造
成员方法:学习,吃饭
得到一个学员类:
成员变量:姓名,年龄、班级、
构造方法:无参构造、带参构造、
成员方法:学习、吃饭、
实现:
学员类:
基础班学员:
就业班学员:
*/
//定义一个抽象学员类:
abstract class Student{
private String name;
private int age;
private String grand;//班级
public Student (){} // 无参构造
public Student (String name,int age,String grand){
this.name = name;
this.age = age;
this.grand = grand;
}
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 setGrand(String grand){
this.grand = grand;
}
public String getGrand(){
return grand ;
}
//学生类:学习,吃饭
//学习:
public abstract void study();
//吃饭:
public void eat(){
System.out.println("学习饿了就吃饭");
}
}
//基础班学员类
class BasicsStudent extends Student{
public BasicsStudent (){} // 无参构造
public BasicsStudent(String name ,int age ,String grand){
super(name,age,grand);
}
public void study(){
System.out.println("基础班学习的是javaSE");
}
}
//就业班学员:
class workStudent extends Student{
public workStudent (){}
public workStudent (String name,int age ,String grand){
super(name,age,grand);
}
public void study(){
System.out.println("就业班学习的是javaEE");
}
}
public class AbstractTest3 {
public static void main(String []args){
//多态调用:
Student s = new BasicsStudent();
s.setName("zhangsan");
s.setAge(23);
s.setGrand("一班");
System.out.println(s.getName() + "---" + s.getAge() + "---" + s.getGrand());
s.eat();
s.study();
System.out.println("--------------------------------");
s = new workStudent();
s.setName("庄心妍");
s.setAge(24);
s.setGrand("三班");
System.out.println(s.getName() + "---" + s.getAge() + "---" +s.getGrand());
s.eat();
s.study();
s = new workStudent("林青霞",23,"五班");
System.out.println(s.getName() + "---" + s.getAge() + "---" + s.getGrand());
s.eat();
s.study();
System.out.println("----------------------------------");
BasicsStudent bs = new BasicsStudent();
bs.setName("ZHANGSAN");
bs.setAge(23);
bs.setGrand("二班");
System.out.println(bs.getName() + "---" + bs.getAge() + "---" + bs.getGrand());
bs.eat();
bs.study();
}
}
抽象类的问题:
1、一个类如果没有抽象方法,时候可以定义为抽象类,如果可以,是否有什么意义:
可以;
意义:
不让外界创建对象,如果要访问,只能通过该子类去使用,
2、abstract(抽象类)不能和那些关键字共存:
私有的:private 冲突
私有不能被继承,不能被继承就不能被重写,而抽象要求重写;
最终的:final 冲突
最终的不能被重写,而抽象的要求重写;
静态的:static 无意义;
接口:
接口特点:
接口用关键字:interface表示
格式:intface 接口名 { }
intface AnimalTrain{ }
类实现接口用关键字:implements 表现
class 类名 implements 接口名{ }
接口不能实例化;
实例化方法:
按照多态的方式实例化;
接口子类:
a、可以是抽象类,但是意义不大;
b、可以是具体类,但是要重写接口中所有的抽象方法;(推荐)
1、具体类多态:(几乎没有)
2、抽象类多态:(常用)
3、接口多态(最常用)
接口的成员特点:
接口中的变量默认是常量;
成员变量:只能是常量,并且是静态的,
因为有默认修饰符:public static final
完整版的接口变量:public static final int num =30;(建议手动给出)
构造方法:接口没有构造方法;
所有的类默认继承自一个类:Object
类 Object 是类层次结构的根类,没有个类都使用Object作为超类;
成员方法:
只能是抽象方法
默认修饰符:public abstract
建议手动给出;
//接口名 + Impl 这种格式是接口的实现类格式;
class InterImpl implement Inter{
public InterImpl(){
super();
}
}
//等价于
class InterImpl extends Object implements Inter{
public InterImpl(){
super();
}
}
类与类:继承关系,只能是单继承,可以多层继承
类与接口:实现关系可以单实现,也可以多实现,并且还可以在继承一个类的同时实现多个接口;
接口与接口:继承关系可以是单继承,也可也是多继承,
抽象类和接口的区别:
抽象类:
成员变量:可以变量,也可以是常量
构造方法:有
成员方法:可以抽象,也可以是非抽象;
接口:
成员变量:只能是常量;
成员方法:只可以抽象;
构造方法:(没有)
关系区别:
类与类:继承,单继承
类与接口:实现,单实现,多实现,
接口与接口:继承,单继承,多继承;
设计理念不同:
抽象类 被继承体现的是 is a 的关系,抽象类中定义的是该继体系的共性功能(什么是什么)
接口 被实现体现的是:like a 的关系;接口中定义的是继承体系的扩展功能;
链式编程特点:
每次调用完毕,返回的是一个对象;
包的概述:
1、其实就是文件夹
2、作用:
对类进行分类管理
把相同的类名放到不同的包中
举例:
学生:增加、删除、修改、查询;
老师:增加、删除、修改、查询;
按照功能分:
cn.itcast.add //增加
AddStudent
AddTeacher
cn.itcast.delete //删除
DeleteStudent
DeleteTeacher
cn.itcast.update //修改
UpdateStudent
UpdateTeacher
cn.itcast.find //查询
FindStudent
FindTeacher
按照模块分:
cn.itcast.Student
AddStudent
DeleteStuent
UpdateStudent
FindStudent
cn.itcast.teacher
AddTeacher
DeleteTeacher
UpdateTeacher
FindTeacher
包的定义:
package 包名;
多级包用.分开即可;
注意事项:
1、package语句必须是程序的第一条可执行代码;
2、package语句在一个java文件只能有一个;
3、如果没有package,则默认表示无包名;
导包:
格式:import 包名 //import java.util.Scanner;
这种方式导入是到类的名称;(用谁就导谁,尽量不使用*)
package,import,class有没有顺序关系:
package > import > class
package :只能有一个
import: 可以有多个
class:可以有多个,但是建议是一个(以为每一个类就是一个单元)
权限修饰符:
private
默认(void )
protected
public
public | protected | 默认 | private | |
---|---|---|---|---|
同一类中 | √ | √ | √ | √ |
同一包、子类中,其他类 | √ | √ | √ | |
不同包子类 | √ | √ | ||
不同包其他类 | √ |
修饰符:
权限修饰符:public 、protected 、默认、 private
状态修饰符:static 、final
抽象修饰符:abstract
类:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public
成员变量:
权限修饰符:public 、protected、默认、private
状态修饰符:static 、final;
抽象修饰符:(不行)
用的最多的就是:private;
构造方法:
权限修饰符:private、默认的、protected、public
用的最多的就是:public
成员变量:
权限修饰符:private、默认、protected、public
状态修饰符:static、final
抽象修饰符:abstract
用的最多的是:public;
内部类的概述:
定义:把类定义在其他类的内部,这个类就被称为内部类(在类a中定义一个类b,类b就是内部类;)
特点:
1、内部类可以直接访问外部类的成员,包括私有;
2、外部类要访问内部类的成员,必须创建对象;
内部类的位置:
成员位置:在成员位置定义的类,被称为成员内部类;
局部位置:(方法里面)在局部位置定义的类称为局部内部类;
成员内部类:
如何直接访问内部类成员;
外部类.内部类名 对象名 = 外部类对象 . 内部类对象;
Other . Inner oi = new Other() . new Inner();
class Other{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
}
public class innerClassDemo {
public static void main(String []args){
//需求:访问Inner 类中的show方法;
// Inner i = new Inner();
// i.show();
//格式:外部类名. 内部类名 对象名 = 外部类名 . 内部类名;
Other . Inner oi = new Other() . new Inner();
oi.show();
}
}
成员内部类的常见修饰符:
1、private为了保证数据的安全性;
2、static为了让数据访问更加便捷
被静态修饰的成员内部类只能访问外部类的静态成员;
内部类被静态修饰后的方法:
静态
非静态;
内部类的和外部类没有继承关系
通过外部类限制this对象;
/*
面试题:
要求:分别输出30/20/10
注意:
1、内部类和外部类没有继承关系
2、通过外部类名限制this对象
*/
class Other {
public int num = 10;
class Inner{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);//当前类的引用
//System.out.println(new Other().num);
System.out.println(Other.this.num);
}
}
}
public class InnerClassTest {
public static void main(String []args){
Other.Inner oi = new Other().new Inner();
oi.show();
}
}
局部内部类:
/*
局部内部类:
1:可以直接访问外部类的成员:
2:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类的成员;
面试题:局部内部类访问局部变量的注意事项:
1、局部内部类访问成员变量必须使用final修饰(不一定要用final修饰,因为根据jak的版本来。版本高的可以不用)
原因:局部变量随着方法的调用而调用,随着调用完毕而消失,
而堆内存的内容不会立即消失,所以我们用final修饰;
*/
class Other1 {
private int num = 10;
public void method(){
final int num2 = 20; //这里的final是可有可无的,根据jak的版本来的(加了final就自动变成常量了)
class Inner{
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
Inner i = new Inner(); //创建内部类对象;
i.show();
}
}
public class InnerClassDemo3 {
public static void main(String []args){
Other1 o = new Other1();
o.method();
}
}
匿名内部类:
就是内部类的简化写法;
前提:
1、存在一个类或者接口
这里的类可以是具体类或者抽象类;
九九乘法表
public class test {
public static void main(String[] args) {
int n = 1;
for (int x = 1; x <= 9; x++) {
for (int y = 1; y <= x; y++) {
System.out.print(y + " * " + x + " = " + x * y + "\t");
}
System.out.println();
}
}
}
API:应用程序编程接口;(就是jdk中提供各种功能的java类)
object是默认继承的,写不写都不会报错:
public class Studnet extends Object{
public static void main(String []aargs){
System.out.println("java");
}
}
Scanner
常用的两个方法:
1、public int nextInt(); 获取一个int类型的值
2、public String nextLine(); 获取一个String 类型的值
注意:先获取一个数值,在获取一个字符串,就会出问题,
主要原因是换行符号的问题
解决方法:
1、先获取一个数值,在创建一个新的键盘录入对象;
2、把所有的数据按照字符串获取,然后要什么就对应的转换;*/
String:
- 字符串就是多个字符组成的数据,也可以看成是字符数组;
*1、字符串字面值“abc”可以看成是一个字符串对象; 2、字符串被赋值后,就不能被改变了
构造方法:
- public String ();空构造
- public String (byte[] bytes); 把字节数组转换为字符串
- public String (byte[] bytes, int index ,int length); 把字节数组的一 部分转成字符串
- public String (char[] value) 把字符数组转换成字符串
- public String (char[] value,int index ,int length); 把字符数组的一部分转换为字符串
public String (String original) 把字符串常量转换为字符串;
String被赋值就不能被改变了(值不改变)
- 字符串直接赋值的方式是先到字符串常量池里面去找,如果有就直接返回,没有的话就创建再返回
面试题:String s = new String (“hello”)和String s = “hello”的区别
- 有区别:前者会创建两个或者一个或者0个对象,而后者会创建一个对象,
- == 比较引用类型的地址值是否相同
- equals比较引用类型默认也是比较的是地址值,而String类重写了equals()方法,比较的内容是否相同
- 字符串如果是变量相加,先开空间,再拼接
- 字符串如果是常量相加,是先加,然后再常量池里面找,如果有就直接返回,否则就创建
- 判断功能:
- boolean equals (Object obj) ;比较字符串的内容是否相同,区分大小写(密码)
- boolean equalsIgnoreCase (String str); 比较字符串的内容是否相同,不区分大小写(验证码)
- boolean contains (String str) 判断大字符串里面是否包含了小字符串
- boolean startsWith(String str) 判断字符串是否以某一个指定字符串开头
- boolean endsWith(String str) 判断字符串是否以某一个指定字符串开头
- boolean isEmpty() 判断字符串是否为空
- 注意:
- 字符串内容为空:对象存在,没有数据
- 字符串对象为空:对象不存在
String 类的获取功能
- int length() 获取字符串的长度
- char charAt(int index) 获取指定索引的字符
- int indexOf(int ch) 返回指定字符在此字符串中第一次出现的索引
- int indexOf(String str) 返回指定字符串在此字符串中第一次出现的索引
- int indexOf(int ch ,int fromIndex) 返回指定字符在此字符串中指定位置后出现的第一次索引
- int indexOf(String str,int fromIndex) 返回指定字符串在此字符串中指定位置后出现的第一次索引
- String substring(int start) 从指定位置开始截取字符串,默认到末尾结束
- String substring(int start ,int end) 从指定位置开始到指定位置结束截取字符串
String的转换功能
- byte[] getBytes() 把字符串转换为字节数组
- char [] toCharArray() 把字符串转为字符数组
- static String valueOf(char[] chs) 把字符数组转换为字符串
- static String valueOf(int i) 把int类型的数据转换为字符串
- 注意;String 类的valueOf 方法可以把任意类型的数据转换为字符串
- String toLowerCase() 把字符串转换为小写
- String toUpperCase() 把字符串转换为大写
- String concat(String str) 字符串拼接
String 类的其他功能
- 替换功能:
- String replace (char old , char new)
- String replace (String old ,String new)
- 替换功能:
- 去除字符串两空格
- String trim()
- <br />
- 按照字典顺序比价两个字符串a-z
- int compareTo(String str)区分大小写
- int compareToIgnoreCase(String str)不区分大小写
StringBuffer
- 线程安全
- 安全 — 同步 — 数据是安全的 (缺点:效率低)*
- 不安全 — 不同步 — 效率高 (缺点:数据不安全)*
- 安全: 医院网站,银行网站*
- 不安全:论坛,新闻……
StringBuffer :线程安全的可变字符串
*
StringBuffer和String 的区别
StringBuffer:长度和内容可变的
String : 长度和内容是不可变的
使用StringBuffer做字符串的拼接,不会有太大资源的浪费;
StringBuffer的构造方法:
public StringBuffer () 无参构造
public StringBuffer (int capacity); 指定容量的字符串缓冲区对象
public StringBuffer (String str) 指定字符串内容的字符串缓冲区对象;
StringBuffer 的方法
public int capacity () 返回当前容量 理论值
public int length () 返回长度(字符数) 实际值
StringBuffer 的添加功能:
public StringBuffer append (String str) 可以把任意类型数据添加到字符缓冲区里面,并放回字符串缓冲区本身
public StringBuffer insert(int office ,String str) 在指定位置在任意把任意类型的数据插入到字符串缓冲区
StringBuffer的删除功能
- public StringBuffer deleteChat(int index ) 删除指定位置的字符,并返回本身
- public StringBuffer delete(in start ,int end ) 删除从指定位置开始到指定位置结束的内容,并返回
替换功能
- public StringBuffer replace (int start ,int end , String str) 从start开始的 到end结束,用str替换
StringBuffer 的反转功能
- public StringBuffer reverse ()
StringBuffer 截取功能(返回值本身不再是StringBuffer本身)
- 截取功能:
- public String substring(int start) //本身不变
- public String substring(int start ,int end)
面试题:String ,StringBuffer ,StringBuilder 的区别:
a、String的内容是不可变的,而StringBuffer 和StringBuilder 的内容是可变的
b、StringBuffer 是同步的,数据安全,但是效率低
StringBuild 是不同步的,数据是不安全的,效率高
StringBuffer 和数组的区别:
二者都是一个容器,装其他的数据
但是StringBuffer 的数据最终是字符串数据
而数组可以防止多种数组,但是必须是同一类型的的
形式参数的问题:(看程序写结果)
String作为参数传递
StringBuffer最为参数传递
形式参数:
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
String作文形参传递,效果和基本类型作为参数传递的效果是一样的
String和StringBuffer类型的转换
- a转b 其实就是为了使用b的功能
- b转a 可能要的结果是a的类型,所以还要转回来
判断一个字符串是否为对称字符串
- 例如abc就不是字符串,aba、abba、mnanm是对称字符串
- 分析:
- 判断一个字符串是否为对称字符串,只需要
- 第一个和最后一个比较
- 第二个和倒数第二个比较
- 第三个和倒数第三个比较
- ……
- 比较的次数/2
冒泡排序:
相邻元素两两比较,大的往后放,第一次比完后最大值就出现在最大索引处,同理,继续操作就得到了一个排好序的数组
规律:
1、两两比较,大的往后放
2、每一次比较完,下一次比较就会减少一个元素,的比较
3、第一次比较:有0个元素比较
第二次比较:有1个元素不比
第三次比较:有2个元素不比
……
4、总共需要比较的数组长度-1次
package cn.deng_01;
/**
* 排序数组值冒泡排序:
* 相邻两个元素两两比较,大的往后放,第一次比比较完,最大值出现在最大的索引处
*/
public class ArrayDemo {
public static void main(String[] args) {
//定义一个数组;
int[] arr = {24, 69, 80, 57, 13, 34, 346, 67, 23};
System.out.println("排序前: ");
printArray(arr);
//调用方法:
System.out.println("\n" + "终极版冒泡排序: ");
bubbleSort(arr);
printArray(arr);
/*
//第一次比较:
//arr.length-1这里为了防止数据越界,索引要-1
for (int x = 0; x < arr.length - 1 - 0; x++) { //这里x++最大取到4,但是下面arr[x+1]了所以就相当于没减,
// (取到了最大长度,数组索引不能到最大长度,只能数组长度减1)
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println();
System.out.println("第一次排序:");
printArray(arr);
//第二次比较:
//arr.length -1 是为了防止数据越界
//arr.length - 1 -1 是为了减少比较的次数
for (int x = 0; x < arr.length - 1 - 1; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println();
System.out.println("第二次排序: ");
printArray(arr);
//第三次比较:
for (int x = 0; x < arr.length - 1 - 2; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println();
System.out.println("第三次排序: ");
printArray(arr);
//第四次排序
for (int x = 0; x < arr.length - 1 - 3; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
System.out.println();
System.out.println("第四次排序: ");
printArray(arr);
*/
//最终版
for (int y = 0; y < arr.length - 1; y++) {//这里arr.length- 1 是为了防止数据越界,这个循环控制的是冒泡排序的次数
for (int x = 0; x < arr.length - 1 - y; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
}
System.out.println("\n" + "排序后:");
printArray(arr);
}
//冒泡排序的功能:
public static void bubbleSort(int[] arr) { //bubbleSort (冒泡排序)
for (int y = 0; y < arr.length - 1; y++) {
for (int x = 0; x < arr.length - 1 - y; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
}
}
//遍历数组:
public static void printArray(int[] arr) {
System.out.print("[");
for (int x = 0; x < arr.length; x++) {
if (x == arr.length - 1) {
System.out.print(arr[x] + "]");
} else {
System.out.print(arr[x] + ", ");
}
}
}
}
选择排序:
从索引0开始,一次和后面的元素比较,小的往前面,第一次完毕后,最小值出现在最小索引处,其他的同理即可以得到一个拍好序的数组;
规则:
1、第一次是从0 索引开始,和其他的进行比较,
第二次是从1索引开始,和其他的进行比较
……
2、最后一次是数组长度-2(倒数第二个元素)和数组长度-1(最后一个元素)比较;
package cn.deng_01;
/**
* 数组排序之选择排序
* 从0索引开始, 依次和后面的元素比较,第一次完毕后,就出现了最小索引值,
* 第二次是从1索引开始,依次和其他的进行比较;
*/
public class ArrayDemo_02 {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13};
System.out.println("排序前: ");
printArray(arr);
/*
//第一次拿索引0开始,与length-1比较
int x = 0;
for (int y = 1; y < arr.length; y++) { //从一到最后一个索引
if (arr[y] < arr[x]) { //判断arr[y]有没有比arr[x]更小的
int temp = arr[x];
arr[x] = arr[y]; //arr[x]在当前就是最小值
arr[y] = temp;
}
}
System.out.println("\n" + "第一次排序: ");
printArray(arr);
//第二次排序:
x = 1;
for (int y = x + 1; y < arr.length; y++) {
if (arr[y] < arr[x]) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("\n" + "第二次排序: ");
printArray(arr);
//第三次排序:
x = 2;
for(int y = x+1;y< arr.length; y++){
if(arr[y] < arr[x]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("\n"+ "第三次排序: ");
printArray(arr);
//第四次排序:
x= 3;
for(int y = x+1; y < arr.length;y++){
if(arr[y] < arr[x]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
System.out.println("\n" + "第四次排序: ");
printArray(arr);
*/
System.out.println("\n"+"--------------------");
for(int x = 0 ;x < arr.length -1 ; x++){
//x = arr.length-1;
for(int y = x+1 ;y< arr.length ;y++){
if(arr[y] < arr[x]){
int temp = arr[x];
arr[x] =arr[y];
arr[y] = temp;
}
}
}
System.out.println("最后排序版: ");
printArray(arr);
System.out.println("\n"+"最后排序版(使用功能) : ");
selectSort(arr);
printArray(arr);
}
//这里写selectSort(选择)功能
public static void selectSort(int [] arr){
for(int x = 0;x < arr.length -1; x++){
for(int y = x+1; y < arr.length; y++){
if(arr[y] < arr[x]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
//遍历数组的功能:
public static void printArray(int[] arr) {
System.out.print("[");
for (int x = 0; x < arr.length; x++) {
if (x == arr.length - 1) {
System.out.print(arr[x] + "]");
} else {
System.out.print(arr[x] + ", ");
}
}
}
}
//遍历数组:
public static void printArray(int[] arr) {
System.out.print("[");
for (int x = 0; x < arr.length; x++) {
if (x == arr.length - 1) {
System.out.print(arr[x] + "]");
} else {
System.out.print(arr[x] + ", ");
}
}
}
//冒泡排序
public static void bubbleSort(int[] arr) { //bubbleSort (冒泡排序)
for (int y = 0; y < arr.length - 1; y++) {
for (int x = 0; x < arr.length - 1 - y; x++) {
if (arr[x] > arr[x + 1]) {
int temp = arr[x];
arr[x] = arr[x + 1];
arr[x + 1] = temp;
}
}
}
}
//选择排序
private static void bubbleSort(char[] chs) {
for( int y = 0 ;y < chs.length -1 ;y ++){
for(int x =0 ; x< chs.length -1-y;x++){
if(chs [x] > chs[x+1]){
char temp = chs[x];
chs [x] = chs[x+1];
chs[x+1] = temp;
}
}
}
}
Arrays的排序和查找功能
package cn.Arrays;
import java.util.Arrays;
/**
* Arrays 针对数组进行操作的工具类比如说排序,查找
* 1、public static String toString(int [a]) 把数组转成字符串;
* 2、public static void sort(int [] arr) 对数组进行排序 (底层是快速排序)
* 3、public static int binarySearch(int [] ,int key) 二分查找
*
* */
public class ArraysDemo {
public static void main(String[] args) {
int[] arr = {24,69,80,57,13,23,34};
//public static String toString(int [a]) 把数组转换成字符串
System.out.println("排序前: "+Arrays.toString(arr));
//public static void sort (int [] arr) 对数组进行排序
Arrays.sort(arr);
System.out.println("排序后: " + Arrays.toString(arr));
//public static int binarySearch(int [],int key) 二分查找;
//排序后: [13, 24, 57, 69, 80]在排序后的基础上使用binarySearch(int [],int key)
// 0 1 2 3 4
System.out.println("binarySearch: " + Arrays.binarySearch(arr,2000));
}
}
Integer
把100的二进制、八进制、十六进制输出
二进制输出:
public static String toBinaryString(int i) Binary 二进制
八进制输出:
public static String toOctalString(int i) Octal 八进制
十六进制输出:
public static String toHexString(int i); Hex 十六进制
十进制到其他进制的输出:(进制的范围2-36)
public static String toString(int i ,int radix) int i是原值,int radix 是需要修改的进制
(注:使用方法和二进制、八进制、十六进制一样)
(进制的范围2-36)0-9 和a-z可以表示进制,所以进制的最大值是36
其他进制转换到10进制
public static int parseInt(”100”,10/2/8/16); //转换字符串为int
判断一个数据是否在int范围 *
public static final int MAXVALUE;
public static final int MIN_VALUE;
为了对基本数据类型进行更多的操作,更方便的操作,java就针对每一种基本数据类型提供了对应的类类型。。包装类类型
int Integer
char Character
byte Byte
short Short
long Long
float Float
double Double
boolean Boolean
用于基本数据类型与字符串之间的转换
Integer 的构造方法:
public Integer(int value)
public Integer(String s ) 这个字符串必须是由数字字符组成
int 和 String 的转换
int—-String
String.valueOf(number)
String—-int
public static int parseInt(String s) //直接把String 转成int
package cn.Integer_03;
/**
* int 和 String 的转换
* int---String
* String.valueOf(number)
*
* String---int
* public static int parseInt(String s) //直接把String 转成int
*/
public class IntegerDemo {
public static void main(String[] args) {
int number = 100;
//方式1:
String s = "" + number; //字符串拼接
System.out.println("s = " + s);
//方式2
String s2 = String.valueOf(s);
System.out.println("s2 = " + s2); //推荐
//方式3
//int--- Integer ---String
Integer i = new Integer(number);
String s3 = i.toString();
System.out.println("s3 = " + s3); //最差
//方式4
// public static String toString(int i )
String s4 = Integer.toString(number);
System.out.println("s4 = " + s4);
System.out.println("-------------------");
//String --- int
String ss = "100";
//方式1
//String --- Integer --- int
//返回Integer 值作为int(即返回值类型为 int)
//public int value()
Integer ii = new Integer(s);
int x = ii.intValue();
System.out.println("x = " + x);
//方式2:
//接收字符串,返回int类型
//public static int parseInt(String s)
int y= Integer.parseInt(s);
System.out.println("y = " + y);
// System.out.println(Integer.parseInt(s));
String sss = "12.3";
float f = Float.parseFloat(sss);
System.out.println("f = " + f);
double d = Double.parseDouble(sss);
System.out.println("d = " + d);
}
}
JDK5的新特性
自动装箱:把基本类型转为包装类类型
自动拆箱:把包装类类型转为基本类型
注意:使用Integer x = null ,会造成控制针异常,所以建议在使用前就先进行判断是否为null,再使用
//针对-128 到127之间的数据,做了一个数据缓冲池,如果数据是该范围的,那么就不再创建新的空间了
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7==i8); //这里为false
System.out.println(i7.equals(i8));
Integer的数据直接赋值时,如果在-128到128之间没回直接在数据缓冲池里获取数据;
Character
public static boolean isUpperCase(char ch); 判断给定字符是不是大写
public static boolean isLowerCase(chat ch); 判断给定字符是不是小写
public static boolean isDigit(char ch); 判断给定字符是不是数字
public static chat toUpperCase(char ch); 把指定的字符转成大写
* public static chat toLowerCase(char ch); 把指定的字符转成小写
正则表达式:
字符:
1、’a’ 表示字符a
2、\反斜杠字符
3、\n换行
4、\r回车符
字符类:
1、[abc] a、b或者c
2、[^abc] 除了a、b、c的任何字符
3、[a-zA-Z] a-z和A-Z,两头的字符都包含在内
4、[0-9] 0-9都包含在内
预定义字符类:
1、. 任何字符,我的就是 . 字符本身, 表示方法:.
2、 \d 数字 [0-9]
3、\w 单词字符:[a-zA-Z_0-9]
在正则表达式里面组成的单词的东西必须有这些
边界匹配器:
1、^行的开头
2、$行的结束
3、\b单词边界
就是不是单词字符的地方:;
举例: hello world?haha;xixi 空格?;都是单词边界
Greedy 数量词
X? X一次或一次都没有
X* X零次或多次
X+ X一次或者多次
X{n} X恰好一次
X{n,} X至少一次
X{n,m} X至少n次,但不超过m次
判断:
public boolean matches(String regex);
分割:
public String[] split(String regex);
替换:
public String replaceALL(String regex String replacement);
获取
Pattern 和 Matcher类的使用:
//硬盘上面的路径\应该用两个\\替代
public class RegexDemo02 {
public static void main(String[] args) {
String s4 = "D:\\javaProject\\day_14\\Regex\\src\\cn\\Regex\\split";
String[] str4Array = s4.split("\\\\");
for(int x = 0; x< str4Array.length; x++){
System.out.println(str4Array[x]);
}
}
}
package cn.Regex02;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 获取功能:
* Pattern 和 Matcher 类的使用
* Pattern 模式对象
* Matcher 匹配器
*
* 模式和匹配器的基本使用顺序
*
* */
public class RegexDemo {
public static void main(String[] args) {
//模式和匹配器典型的调用顺序
//把正则表达式编译成对象:
Pattern p = Pattern.compile("a*b"); //* 表示一个或多个
//通过模式对象得到匹配器对象,这个时候需要的是被匹配的对象
Matcher m = p.matcher("aaaaaab");
//调用匹配器对象的功能
boolean b = m.matches();
System.out.println("b = " + b);
//这十个判断功能, 可以直接用字符串来做:
String s = "aaaaab";
String regex = "a*b";
boolean bb = s.matches(regex); //s 通过matches调用规则
System.out.println("bb = " + bb);
}
}
package cn.Regex02;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 获取功能:
* 获取下面的字符串由三个字符组成的单词
* da jia ting wo shuo ,jin tian yao xia yu ,bu shang wan zi xi ,gao xin bu?
*
* 注意:一定要先find,在group
*
* */
public class RegexDemo_02 {
public static void main(String[] args) {
//定义字符串
String s = "da jia ting wo shuo ,jin tian yao xia yu ,bu shang wan zi xi,dao xin bu?";
//定义规则
String regex = "\\b\\w{3}\\b"; // \\b是单词边界 \w 是单词字符 {3}是范围
//把规则编译成模式对象:
Pattern p = Pattern.compile(regex); //Pattern调用compile方法总的规则(regex)
//通过模式对象得到匹配器对象
Matcher m = p.matcher(s);
/*
这里就是通过p调用matcher 方法(s)
问s匹配p.matcher吗
p.matcher 对应的是regex
regex对应的是"\\b\\w{3}\\b"
*/
//调用匹配器对象的功能
/*
matches 方法尝试将整个序列与该模式Matcher匹配(整体与Matcher匹配)
lookingAt 尝试将输入的序列从头开始与Matcher匹配,通过Start end group 获取更多(Start 和end 返回类型是int, 而group返回的是String类型)
find方法扫描输入序列以查找与模式匹配的下一个子序列, 通过Start end group 获取更多(Start 和end 返回类型是int, 而group返回的是String类型)
*/
//这里通过find方法查找有没有满足条件的序列 public Sting find();
boolean flag = m.find();
System.out.println("flag = " + flag);
//得到满足条件的值,通过Start 、end、 group;
//public String group()
/*
String ss = m.group();
System.out.println("ss = " + ss);
flag = m.find();
System.out.println("flag = " + flag);
ss = m.group();
System.out.println("ss = " + ss);
flag = m.find();
System.out.println("flag = " + flag);
ss = m.group();
System.out.println("ss = " + ss);
*/
//用循环改进
while (m.find()) { //find 方法就是查找有没有满足条件的子序列
System.out.println(m.group());
}
}
}
Math
java中的Math类
package cn.System;
/**
* System 类包含了一些有用的字段和方法,但是不能实例化
*
* 方法:
* public static void gx() 运行垃圾回收器
* public static void exit(int status) 终止当前运行的java虚拟就,参数用作状态码,根据惯例,非0 的状态码表示异常终止
* public static long currentTimeMillis () 返回以毫秒为单位的当前时间
* public static void arraycopy(Object src ,int srcPos ,Object dest,int destPos, int length)
* 从指定源数组中复制一个数组,复制从指定位置开始,到目标数组指定位置结束
* Object src 源数组
* int srcPos 从源数组的起始位置
* Object dest 目标数组
* int destPos 目标数据的起始位置
* int length 要复制数组元素的个数
*
* 从源数组的某个位置开始,复制到目标数组里面,从destPos开始,复制几个
*
*
* */
public class SystemDemo {
public static void main(String[] args) {
//public static void exit(int status) 终止当前java虚拟机
// System.out.println("我爱java");
// System.exit(0); //二选一,只能存在一个 0表示正常
// System.out.println("我爱Python");
//public static long currentTimeMillis() 返回以毫秒为单位的的当前时间
//System.out.println(System.currentTimeMillis()); // /1000/3600/24/356这样可以计算具体时间
//计算时间的意义
//要求:计算如下程序的运行时间
long start = System.currentTimeMillis(); //开始计时
for(int x = 0 ; x<900000; x++){
System.out.println("hello"+x);
}
long end = System.currentTimeMillis(); //停止计时
System.out.println("共耗费时间: "+ (end - start) +"毫秒");
}
}
package cn.Random;
import java.util.Random;
/**
* Random产生的随机数
* 构造方法:
* public Random() 没有给种子,使用的是默认种子,是当前时间的毫秒值
* public Random(long seed) 给出指定的种子
*
* 给定种子后,每次得到的随机数都是相同的
*
* 成员方法:
* public int nextInt():返回的是int范围的随机数
* public int nextInt(int n)返回的是[0,n](包括0 ,不包括n的随机数)
*
*
* */
public class RandomDemo {
public static void main(String[] args) {
//创建对象:
Random r = new Random(); //没有给种子
for(int x = 0 ; x< 10 ;x++){
// int num = r.nextInt();
// System.out.println("num = " + num); //产生10个任意随机数
// System.out.println("--------------");
int num2 = r.nextInt(100)+1;//产生1-100的随机数
System.out.println("num2 = " + num2);
}
}
}
package cn.BigInteger;
import java.math.BigInteger;
/**
* BigInteger 类:
* 可以让超过Integer 范围内的数据进行运算
* 构造方法:
* public BigInteger (String val);
*
*
* */
public class BigIntegerDemo {
public static void main(String[] args) {
Integer i = new Integer(100);
System.out.println("i = " + i);
//System.out.println(Integer.MAX_VALUE); //2147483647
Integer ii = new Integer(2147483647);
System.out.println("ii = " + ii);
// Integer iii = new Integer(2147483648); //这里数据超范围了
// System.out.println("iii = " + iii);
Integer iiii = new Integer(1);
System.out.println("Integer.MAX_VALUE = "+Integer.MAX_VALUE);
System.out.println("--------------------------");
BigInteger bi = new BigInteger("2147483648");
System.out.println("bi = " + bi);
}
}
package cn.BigInteger;
import java.math.BigInteger;
/**
* BigInteger的应用:
* public BigInteger add (BigInteger val); 加
* public BigInteger subtract(BigInteger val) 减
* public BigInteger multiply(BigInteger val) 乘
* public BigInteger divide(BigInteger val) 除
* public BigInteger [] divideAndRemainder(BigInteger val) 返回商和余数的数组
*
*
* */
public class BigIntegerDemo_02 {
public static void main(String[] args) {
BigInteger bi1 = new BigInteger("100");
BigInteger bi2 = new BigInteger("50");
//public BigInteger add(BigInteger val);
System.out.println("add= "+ bi1.add(bi2));
//public BigInteger subtract(BIgInteger val)
System.out.println("subtract= "+bi1.subtract(bi2));
//public BigInteger multiply(BigInteger val);
System.out.println("multiply =" + bi1.multiply(bi2));
//public BigInteger divide(BigInteger val);
System.out.println("multiply= " +bi1.divide(bi2));
//public BigInteger[] divideAndRemainder(BigInteger val)
BigInteger[] bis = bi1.divideAndRemainder(bi2);
System.out.println("商= " +bis[0]);
System.out.println("余数= "+bis[1]);
}
}
package cn.BigDecimal;
import java.math.BigDecimal;
/**
*
* 由于在运算的时候,float和double容易造成数据精度的丢失,为了让数据精确,java提供了BigDecimal方法
* BigDecimal类:是不可变的、任意精度的有符号十进制数,可以解决数据精度丢失的问题
*
*
* BigDecimal:
* 构造方法:
* public BigDecimal (String val)
*
* public BigDecimal add(BigDecimal augend); 加
* public BigDecimal subtract (BigDecimal subtrahend) 减法
* public BigDecimal multiply(BigDecimal multiplicand) 乘
* public BigDecimal divide(BigDecimal divisor) 除
* public BigDecimal divide(BigDecimal divisor, int scale ,int roundingMode) 商:几位小数,如何舍去
* //System.out.println("divide = " + bd7.divide(bd8,3,BigDecimal.ROUND_HALF_UP));
*
* */
public class BigDecimalDemo_02 {
public static void main(String[] args) {
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
System.out.println("--------------");
BigDecimal bd1 = new BigDecimal("0.09");
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("add = " + bd1.add(bd2));
BigDecimal bd3 = new BigDecimal("1.0");
BigDecimal bd4 = new BigDecimal("0.32");
System.out.println("subtract = " + bd3.subtract(bd4));
BigDecimal bd5 = new BigDecimal("1.015");
BigDecimal bd6 = new BigDecimal("100");
System.out.println("multiply = " + bd5.multiply(bd6));
BigDecimal bd7 = new BigDecimal(1.301);
BigDecimal bd8 = new BigDecimal("100");
System.out.println("divide = " + bd7.divide(bd8));
System.out.println("divide = " + bd7.divide(bd8,3,BigDecimal.ROUND_HALF_UP)); //3 表示保留3为小数
}
}
Date
package cn.Date;
import javax.lang.model.SourceVersion;
import java.util.Date;
/**
* Date 表示特定的瞬间,精确到毫秒
* 构造方法:
* Date() 根据当前默认的毫秒值创建对象
* Date(long date) 根据给定的毫秒值创建对象
*
* public long getTime() 获取时间,以毫秒为单位
* public long setTime() 设置时间
*
*
* */
public class DateDemo {
public static void main(String[] args) {
/*
Date d = new Date();
System.out.println("d = "+ d); //输出当前计算机的时间 d = Fri Jul 10 22:28:06 CST 2020
long time = System.currentTimeMillis(); //把当前的毫秒值赋值给long time
Date d2 = new Date(time);
System.out.println("d2 = "+d2); // d2 = Fri Jul 10 22:31:32 CST 2020 d1 的值会等d2 的值
long time2 = 1000*60*60; //1000毫秒就是1秒,1*60*60 = 1h
Date d3 = new Date(time2);
System.out.println("d3 = " + d3); //d3 = Thu Jan 01 09:00:00 CST 1970
//时间本来从1970年7月1日零点开始,但是这里因位东八区的原因,时间相差八个小时
*/
//创建对象
Date d = new Date();
System.out.println("d = " + d);//获取当前时间
System.out.println("-----------");
//获取时间
long time = d.getTime();
System.out.println("time = " + time);
System.out.println("System.currentTimeMillis = "+System.currentTimeMillis());
System.out.println("d = "+ d); //当前计算机的时间
//设置时间
d.setTime(1000);
System.out.println("d = " + d);
}
}
package cn.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Date 转 String
* public final String format(Date date)
*
* String 转 Date
* public Date parse(String source);
*
* DateFormat :可以进行日期和字符串的格式化,但由于是抽象类,所以要使用具体子类的SimpleDateFormat
*
* SimpleDateFormat 的构造方法
* SimpleDateFormat() 默认格式
* SimpleDateFormat(String pattern) 给定格式
* 通过API 可以找到对应的模式
* 年 y
* 月 M
* 日 d
* 时 H
* 分 m
* 秒 s
*
*
* */
public class DateFormatDemo {
public static void main(String [] args) throws ParseException {
//Date 转 String
Date d = new Date();
//创建格式化对象
SimpleDateFormat sdf = new SimpleDateFormat(); //默认模式
//public final String format(Date date)
String s = sdf.format(d);
System.out.println("现在时间s = " + s);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年 MM月 dd日 HH:mm:ss"); //给定模式
String ss = sdf2.format(d);
System.out.println("ss = " + ss);
//String 转 Date
String str = "2020-07-11 00:00:23";
//把字符串解析为日期时,要注意格式必须和给定的格式一致
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date dd = sdf3.parse(str);
System.out.println("dd = " + dd);
}
}
DateUtil
package cn.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 这是日期和字符串相互转换的工具类
* @author dengtonghu
*/
public class DateUtil {
private DateUtil() {//构造私有,不让别人造对象
}
//从一个日期到字符串
/**
* @param d 被转换的日期对象
* @param format 传递过来要被转换的格式
* @return 格式化后的字符串
*/
public static String dateToString(Date d, String format) {
// SimpleDateFormat sdf = new SimpleDateFormat(format);
// return sdf.format(d);
return new SimpleDateFormat(format).format(d);
}
/**
* @param s 被解析的字符串
*
* @param format 传递过来要被转换的格式
*
* @return 解析后的日期对象
*
* @throws ParseException 抛出异常
* */
public static Date stringToDate(String s, String format) throws ParseException {
return new SimpleDateFormat(format).parse(s);
}
}
package cn.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
/**
* 计算出生多少天
* 分析:
* 1、键盘录入
* 2、把该字符串转为一个Date日期 (parse)
* 3、通过该日期得到一个毫秒值
* 4、获取当前时间的毫米值
* 5、用4-3得到区间毫秒值
* 6、把5的毫秒值转为年
* /1000/60/60/24 1000就是一秒
*
*
* */
public class AgeTest {
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的出生年月(格式为:yyyy-MM-dd):");
String line = sc.nextLine();
//把给字符串转为一个Date日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(line); //这里解析得到一个Date日期
//通过日期得到一个毫秒值
long Mytime = d.getTime();
//得到当前时间的毫秒值
long nowtime = System.currentTimeMillis();
//区间毫秒值
long time = nowtime- Mytime;
//把区间毫秒值转为年
//int day= (time/1000/60/60/24); //用int会造成数据类型不对
long day= (time/1000/60/60/24);
long yaer = time/1000/60/60/24/365;
System.out.println("你来到这个世界已经 = " + yaer + "年了");
System.out.println("你来到这个世界已经: "+ day+"天了" );
}
}
Calendar
package cn.Calendar;
import java.util.Calendar;
/**
* Calendar:它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR 等一些日历字段之间转换提供了一下方法,
*
* public int get(int field) 返回给定日历的字段值,日历类中的每个字段都是静态的,并且是int类型的
*
*
*
* */
public class CalendarDemo {
public static void main(String[] args) {
Calendar rightNow = Calendar.getInstance(); //相当于得到了一个日历对象
int year = rightNow.get(Calendar.YEAR);
int month = rightNow.get(Calendar.MONTH)+1; //+1 是因为月份是从0开始到11月就结束了,所以+1
int day = rightNow.get(Calendar.DAY_OF_MONTH);
System.out.println(year+"年"+month+"月" +day+"日");
int hour = rightNow.get(Calendar.HOUR);
int minute = rightNow.get(Calendar.MINUTE);
int second = rightNow.get(Calendar.SECOND);
System.out.println(hour+":"+minute+":"+second);
}
}
package cn.Calendar;
import java.util.Calendar;
/**
* public void add(int field,int amount) 根据给定的日历字段和对应的时间,来对当前日历进行操作
* public final void set(int year,int month,int date) 设置当前日历的年月日
*
* */
public class CalendarDemo_02 {
public static void main(String[] args) {
Calendar rightNow = Calendar.getInstance(); //得到一个日历对象
int year = rightNow.get(Calendar.YEAR);
int month = rightNow.get(Calendar.MONTH) + 1;
int day = rightNow.get(Calendar.DAY_OF_MONTH);
System.out.println(year + "年" + month + "月" + day + "天");
//得到三年前的今天
// rightNow.add(Calendar.YEAR, -3);
// int YEAR = rightNow.get(Calendar.YEAR);
// int MONTH = rightNow.get(Calendar.MONTH) + 1;
// int DAY = rightNow.get(Calendar.DAY_OF_MONTH);
// System.out.println(YEAR + "年" + MONTH + "月" + DAY + "日");
//六年后的10天前
rightNow.add(Calendar.YEAR, +6);
rightNow.add(Calendar.DAY_OF_MONTH, -10);
int YEAR1 = rightNow.get(Calendar.YEAR);
int MONTH1 = rightNow.get(Calendar.MONTH) + 1;
int DAY1 = rightNow.get(Calendar.DAY_OF_MONTH);
System.out.println(YEAR1 + "年" + MONTH1 + "月" + DAY1 + "日");
System.out.println("-------------------------");
//设置年月日
rightNow.set(2050, 7, 1);
int year2 = rightNow.get(Calendar.YEAR);
int month2 = rightNow.get(Calendar.MONTH); //这里没有+1,时间是0-11的
int day2 = rightNow.get(Calendar.DAY_OF_MONTH);
System.out.println(year2 + "年" + month2 + "月" + day2 + "日");
}
}