JAVA基础学习(八)------内部类、常用类

JAVA基础学习(八)------内部类、常用类

内部类

  • 分类:成员内部类、静态内部类、局部内部类、匿名内部类

什么是内部类

  • 概念:在一个类的内部再定义一个完整的类

  • 特点:

    1、编译之后可生成独立的字节码文件(格式:外部类名$内部类名.class

    2、内部类可直接访问外部类的私有成员,不破坏封装性

    3、可为外部类提供必要的内部功能组件

成员内部类

  • 在类的内部定义,与实例变量,实例方法是同级别的类

  • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象

  • 当外部类、内部类存下重名属性时,会优先访问内部类属性(打印外部类属性:外部类名.this

  • 成员内部类不能定义静态成员,但是可以包含静态常量

    public class Outer {
        //实例变量
        private String name = "zzz";
        private int age = 21;
    
        //内部类
        public class Inner {
            private String address = "地址";
            private String phone = "187xxx";
            private String name = "mmm";
            private static final String code = "123";
            //方法
            public void show() {
                //属性和外部类属性名字相同,访问外部类属性时加Outer.this
                //打印外部类
                System.out.println(Outer.this.name);
                System.out.println(age);
    
                //打印内部类
                System.out.println(name);
                System.out.println(address);
                System.out.println(phone);
                System.out.println(code);
            }
        }
    }
    
    public class TestOuter {
        public static void main(String[] args) {
            //创建外部类对象
            Outer outer = new Outer();
            //创建内部类对象
            Outer.Inner inner = outer.new Inner();
            //一步到位
            Outer.Inner inner1 = new Outer().new Inner();
    
            inner.show();
        }
    }
    
    

静态内部类

  • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员

  • 只有静态内部类才可以被static修饰

  • 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)

    //外部类
    public class Outer {
        private String name = "zzz";
        private int age = 21;
        //静态内部类 级别和外部类相同(和外部类使用方法相同)
        static class Inner{
            private String address = "地址";
            private String phone = "187xxx";
            //可包含静态成员
            private static int count = 1000;
    
            public void show(){
                //调用外部类属性
                //创建外部类对象
                Outer outer = new Outer();
                //调用外部类对象属性
                System.out.println(outer.age);
                System.out.println(outer.name);
                //调用静态内部类属性和方法
                System.out.println(address);
                System.out.println(phone);
                //调用静态内部类的静态属性
                System.out.println(Inner.count);
            }
        }
    }
    
    public class TestOuter {
        public static void main(String[] args) {
            //直接创建静态内部类
            Outer.Inner inner = new Outer.Inner();
            //调用方法
            inner.show();
        }
    }
    

局部内部类

  • 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

  • 局部内部类中不能包含静态成员

  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final

  • 限制类的使用范围,只能在当前的方法中使用

    public class Outer {
        private String name = "zzz";
        private int age = 21;
    
        public void show(){
            //定义局部变量
            String address = "地址";
    
            //局部内部类:不能加任何访问修饰符
            class Inner{
                private String phone = "187xxxx";
                private String e_mail = "xxxxxxx@qq.com";
    
                public void showInner(){
                    //访问外部类属性
                    System.out.println(name);
                    System.out.println(age);
                    //访问内部类的属性
                    System.out.println(phone);
                    System.out.println(e_mail);
                    //访问局部变量
                    //jdk1.7要求,变量必须是常量final,jdk1.8自动添加final
                    System.out.println(address);
                }
            }
    
            //创建局部内部类对象
            Inner inner = new Inner();
            inner.showInner();
        }
    
    }
    
    public class TestOuter {
        public static void main(String[] args){
            Outer outer = new Outer();
            outer.show();
        }
    }
    
    

匿名内部类

  • 没有类名的局部内部类(一切特征都与局部内部类相同)

  • 必须继承一个父类或者实现一个接口

  • 定义类,实现类,创建对象的语法合并,只能创建一个该类的对象

  • 优点:减少代码量

  • 缺点:可读性较差

    public class TestUsb {
        public static void main(String[] args) {
            //创建接口类型的变量
            /*
            Usb usb = new Mouse();
            usb.service();
            */
            //局部内部类
          /*
           //使用局部内部类来创建对象
            class Fan implements Usb{
                @Override
                public void service() {
                    System.out.println("风扇开始工作啦");
                }
            }
            */
            //使用匿名内部类来优化
            Usb usb = new Usb(){
                @Override
                public void service() {
                    System.out.println("风扇开始工作啦");
                }
            };
            usb.service();
        }
    }
    
    
    public class Mouse implements Usb{
        @Override
        public void service() {
            System.out.println("链接电脑成功,鼠标开始工作");
        }
    }
    
    
    //接口
    public interface Usb {
        //方法
        void service();
    }
    

Object类

  • 超类、基类,所有类的直接或间接父类,位于继承树的最顶层

  • 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承

  • Object类中定义的方法,是所有对象都具备的方法

  • Object类型可以存储任何对象

    作为参数,可接受任何对象,作为返回值,可返回任何对象

Object类常用方法

getClass()方法

  • public final Class<?> getClass () {}

  • 返回引用中存储的实际对象类型

  • 应用:通常用于判断两个引用中实际存储的对象类型是否一致

    public class Student {
        private String name;
      private int age;
    
        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;
        }
    }
    
    
    public class Test {
        public static void main(String[] args) {
            //getClass()方法
            Student s1 = new Student("zzz",21);
            Student s2 = new Student("mmm", 21);
            //判断s1,s2是否是同一个类型
            Class c1 = s1.getClass();
            Class c2 = s2.getClass();
            System.out.println(c1);  //class study.calsss.Demo05.Student
            if(c1==c2){
                System.out.println("s1和s2属于同一个类型");
            }else{
                System.out.println("s1,s2不属于同一个类型");
            }
        }
    }
    

hashCode()方法

  • public int hashCode(){}

  • 返回该对象的哈希码值

  • 哈希值根据对象的地址字符串数字使用hash算法计算出来int类型的数值

  • 一般情况下相同对象返回相同哈希码

    public class Test {
        public static void main(String[] args) {
            Student s1 = new Student("zzz",21);
            Student s2 = new Student("mmm", 21);
            //hashCode()方法
            System.out.println(s1.hashCode());
            System.out.println(s2.hashCode());
            Student s3 = s1;
            System.out.println(s3.hashCode()); //与s1相同
        }
    }
    

toString()方法

  • public String toString(){}

  • 返回该对象的字符串表示(表现形式)

  • 可以根据程序需求覆盖该方法,如:展示对象各个属性值

    public class Test {
        public static void main(String[] args) {
            Student s1 = new Student("zzz",21);
            Student s2 = new Student("mmm", 21);
      
            //toString()方法 可重写
            System.out.println(s1.toString());     //study.calsss.Demo05.Student@4554617c  (@后为哈希值)
            System.out.println(s2.toString());     //study.calsss.Demo05.Student@74a14482
        }
    }
    
    //重写格式
    @Override
        public String toString() {
            return name + ":" + age;
        }
    

equals()方法

  • public boolean equals(Object obj){}

  • 默认实现为(this == obj),比较两个对象地址是否相同

  • 可进行覆盖,比较两个对象的内容是否相同

  • 方法重写步骤

    1、比较两个引用是否指向同一个对象

    2、判断obj是否为null

    3、判断两个引用指向的实际对象类型是否一致

    4、强制类型转换

    5、依次比较各个属性值是否相同

    public class Test {
        public static void main(String[] args) {
            Student s1 = new Student("zzz",21);
            Student s2 = new Student("mmm", 21);
            //equals()方法 判断两个对象是否相等
            System.out.println(s1.equals(s2));   //false
    
            Student s4 = new Student("ttt", 15);
            Student s5 = new Student("ttt", 15);
            System.out.println(s4.equals(s5));    //false 地址不同  重写方法后输出true
        }
    }
    
    
    public class Student {
        private String name;
        private int age;
    
        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;
        }
    
        @Override
        public boolean equals(Object obj) {
            //1.判断两个对象是否是同一个引用
            if(this==obj){
                return true;
            }
            //2.判断obj是否为空
            if(obj==null){
                return false;
            }
            //3.判断是否是同一个类型
           // if(this.getClass()==obj.getClass()){}
            if(obj instanceof Student){
                //4.强制转型
                Student s = (Student)obj;
                //5.比较熟悉
                if(this.name.equals(s.getName())&&this.getAge()==s.getAge()){
                    return true;
                }
            }
            return false;
        }
    }
    

finalize()方法

  • 一般情况下不是由程序员调用的

  • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列

  • 垃圾对象:没有有效引用指向此对象时,为垃圾对象

  • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间

  • 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象

  • 手动回收机制:使用System.gc();通知JVM执行垃圾回收

    public class Student {
        private String name;
        private int age;
    
        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;
        }
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println(this.name+"对象被回收了");
        }
    }
    
    public class Test2 {
        public static void main(String[] args) {
            new Student("aaa", 12);
            new Student("bbb", 13);
            new Student("ccc", 14);
            new Student("ddd", 15);
            new Student("eee", 16);
            //回收垃圾
            System.gc();//控制垃圾回收器
            System.out.println("回收垃圾");
        }
    }
    

包装类

什么是包装类

  • 基本数据类型所对应的引用数据类型
  • Object可统一所有数据,包装类的默认值为null
  • 包装类对应
基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

类型转换与装箱、拆箱

  • 栈里的对象拿到堆里叫:装箱(把基本类型转成引用类型的过程)

    堆里的对象拿到栈里叫:拆箱(把引用类型转成基本类型的过程)

8种包装类提供不同类型间的转换方式:

  • Number父类中提供的6个共性方法

    public class Demo01 {
        public static void main(String[] args) {
            //JDK1.5之前
            //类型转换:装箱,基本类型转换成引用类型的过程
            //基本类型
            int num1 = 18;
            //使用Integer类创建对象
            Integer integer1 = new Integer(num1);
            Integer integer2 = Integer.valueOf(num1);
            System.out.println(integer1);  //18
            System.out.println(integer2);  //18
            System.out.println("==================");
    
            //类型转换:拆箱,引用类型转换成基本类型
            Integer integer3 = new Integer(100);
            int num2 = integer2.intValue();
            System.out.println(num1);      //18
            System.out.println("==================");
    
            //JDK1.5之后,提供自动装箱和拆箱
            //自动装箱
            //int age = 30;
            //Integer integer4 = age;
            Integer integer4 = 30;
            System.out.println(integer4);  //30
            //自动拆箱
            int age = integer4;
            System.out.println(age);       //30
        }
    }
    
  • parseXXX()

    public class Demo02 {
        public static void main(String[] args) {
            //基本类型和字符串之间转换
            //1.基本类型转成字符串
            int n1 = 100;
            int n2 = 15;
            //方法1
            String s1 = n1 + "";
            //方法2
            String s2 = Integer.toString(n1);
            System.out.println(s1);     //100
            System.out.println(s2);     //100
            String s3 = Integer.toString(n2,16);   //输出n2所对应的十六进制
            System.out.println(s3);     //f
            //2.字符串转成基本类型
            String str = "150";   //不能出现非数字的符号 否则会报错NumberFormatException
            //使用Integer.parseXXX()
            int n3 = Integer.parseInt(str);
            System.out.println(n3);
    
            //boolean字符串形式转成基本类型,"true"-->true 非"true"-->false
            String str1 = "tree";
            boolean flag = Boolean.parseBoolean(str1);  //false
            System.out.println(flag);//false
        }
    }
    
  • valueOf()静态方法

    -128127,创建cache数组大小为256,如果赋值在-128127之间,直接在缓冲区中调出该数字,给引用对象赋值,可重复赋值,地址相同;如果没在这个范围内,在堆中new Integer,地址不同。(具体例子见整数缓冲区)

整数缓冲区

  • Java预先创建了256个常用整数包装类型对象

  • 在实际应用当中,对已创建的对象进行复用

    public class Demo03 {
        public static void main(String[] args) {
            //面试题
            Integer integer1 = new Integer(100);
            Integer integer2 = new Integer(100);
            System.out.println(integer1==integer2);   //false 因为是引用类型 存在堆中 地址不同
    
            Integer integer3 = 100;  //自动装箱
            Integer integer4 = 100;
            //自动装箱 : Integer integer3 = Integer.valueOf(100);
            System.out.println(integer3==integer4);   //true
    
            Integer integer5 = 200;
            Integer integer6 = 200;
            System.out.println(integer5==integer6);   //false
        }
    }
    
    
  • valueOf()源码

    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)//-128~127
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    

String类

  • 字符串是常量,创建之后不可改变
  • 给字符串重新赋值时,没有修改数据,而是重新开辟空间,原数据若没人利用变为垃圾
  • 字符串字面值存储在字符串池(方法区)中,可以共享,共享是地址相同
  • String s = "Hello";产生一个对象,在字符串池中存储
  • String s = new String("Hello");,产生两个对象,堆里一个字符串池一个,new关键字产生两个对象
public class Demo01 {
    public static void main(String[] args) {
        String name = "hello";   //“hello”常量存储在字符串池中
        //重新赋值时,并没有把“hello”改为“zzz” ,而是在字符串池中重新开辟一块空间,其中数据为“zzz”
        //此时 栈中的name指向“zzz”  ,“hello”若后续无人用,则变为垃圾
        name = "zzz"; //把zzz赋值给name变量

        //程序去字符串池中,找有没有zzz这个变量,如果有直接指向,没有在字符串池中创建
        String name2 = "zzz";

        //字符串的另一种创建方式
        String s = new String("Java");//这种方式可能会浪费空间
        String s2 = new String("Java");
        System.out.println(s==s2);          //false  指向堆中不同对象 因为new了两次 创建了两个对象
        System.out.println(s.equals(s2));   //true   因为比的不是地址 是数据
    }
}

常用方法

1、public int length():返回字符串的长度

2、public char charAt(int index):根据下标获取字符

3、public boolean contains(String str):判断是否包含某个字符串

public class Demo02 {
    public static void main(String[] args) {
        //字符串方法的使用
        String content = "java编程语言";
        //length()返回字符串长度
        System.out.println(content.length());   //8
        System.out.println("---------------------------");
        //charAt(int index)返回某个位置的字符
        //超过字符串角标范围会出现异常
        System.out.println(content.charAt(4));   //编
        System.out.println(content.charAt(content.length()-1));//获得最后一个  言
        System.out.println("---------------------------");
        //contains(String str)判断是否包含某个字符串
        System.out.println(content.contains("java"));  //true
        System.out.println(content.contains("php"));   //false
    }
}

4、public char[] toCharArray():将字符串换成数组

5、public int indexOf(String str):查找str首次出现的下标,存在,返回该下标,不存在返回-1

6、public int lastIndexOf(String str):查找字符串中最后出现的下标索引

public class Demo03 {
    public static void main(String[] args) {
        //字符串方法的使用2
        String content = "java编程java语言java";
        //toCharArray()返回字符串对应的数组
        System.out.println(content.toCharArray());//直接这样打印出的数组不显示位置
        System.out.println(Arrays.toString(content.toCharArray())); //这样打印出来分位置
        System.out.println("---------------------------");
        //indexOf(String str)返回子字符串首次出现的位置 字符串的话是输出第一个字符下标
        System.out.println(content.indexOf("java"));  //0
        System.out.println(content.indexOf("java",4));  //6   从4下标开始找
        System.out.println(content.indexOf("a"));     //1
        System.out.println("---------------------------");
        //lastIndexOf(String str);返回子字符串最后一次出现的位置
        System.out.println(content.lastIndexOf("java")); //12
        System.out.println(content.lastIndexOf("a"));    //15
    }
}

7、public String trim():去掉字符串前后的空格

8、public String toUpperCase():将小写转成大写

9、public String toLowerCase():把大写转成小写

10、public boolean endWith(String str):判断字符串是否以str结尾

11、public boolean startWith(String str):判断字符串是否以str开头

public class Demo04 {
    public static void main(String[] args) {
        //字符串方法的使用3
        String content1 = "  hello world  ";
        String content2 = "  HELLO WORLD  ";
        String content3 = "hello.java";
        //trim()去掉字符串前后的空格
        System.out.println(content1.trim());
        System.out.println("------------------------");
        //toUperCase()把小写转换成大写    toLowerCase()把大写转换成小写
        System.out.println(content1.toUpperCase());
        System.out.println(content2.toLowerCase());
        System.out.println("------------------------");
        //endWith(String str)判断是否以str结尾  startWith(String str)判断是否以str开头
        System.out.println(content3.endsWith(".java"));    //true
        System.out.println(content3.startsWith("java"));   //false
    }
}

12、public String replace(char oldChar,char newChar):将旧字符或字符串替换成新字符或字符串

13、public String[] split(String str):根据str做拆分 返回值是String数组

14、public boolean equals(String str):比较两个字符串是否相等

15、public boolean equalsIgnoreCase(String str):忽略大小写的比较两个字符串是否相等

16、public int compareTo(String anotherString):比较两个字符串的大小 在字典表(编码表)里的顺序 谁先谁后 做减法

public class Demo05 {
    public static void main(String[] args) {
        //字符串方法的使用4
        String content = "java编程java语言java";
        //replace(char old,char new)用新的字符或字符串替换旧的字符或字符串
        System.out.println(content.replace("java","python"));
        System.out.println("----------------------------");

        //split()对字符串进行拆分
        //如果被拆分的字符串没有“ ” 则拆分的时候默认第一个位置加空格
        String content1 = "java is the best,java is programing  language";
        String[] str = content1.split("[ ,]+");//以“ ”和“,”分割   “+”代表[]中的元素可出现多个
        System.out.println(str.length);
        for (String string:str) {
            System.out.println(string);
        }
        System.out.println("----------------------------");

        //equals()比较两个字符串是否相等   equalsIgnoreCase()忽略大小写的比较
        String s1 = "hello";
        String s2 = "Hello";
        String s3 = "hello";
        System.out.println(s1.equals(s2));             //false
        System.out.println(s1.equals(s3));             //true
        System.out.println(s1.equalsIgnoreCase(s2));   //true
        System.out.println("----------------------------");

        //compareTo(String anotherString)比较两个字符串的大小  在字典表(编码表)里的顺序 谁先谁后
        String s4 = "abc";  //a = 97
        String s5 = "xyza";  //x = 120
        //先用s4的第一个字符和s5的第一个字符做减法  a=97  x=120
        //如果不等 则输出a-x=-23  如果相等继续比较第二个
        //如果所有都相等 输出0
        System.out.println(s4.compareTo(s5));  //-23

        String s6 = "abc";
        String s7 = "abcdef";
        //一个比另一个长且 其中一个完全和另一个的前半部分相同 则比较长度 
        System.out.println(s6.compareTo(s7));   //-3
    }
}

案例演示

需求:

  • 一直String str = “this is a text”;

  • 将str中的单词单独获取出来

  • 将str中的str中的text替换为practice

  • 在text前面插入一个easy

  • 将每个单词的首字母改为大写

    public class Demo06 {
        public static void main(String[] args) {
            String str = "this is a text";
            //将单词单独提取出来
            String[] strings = str.split(" ");
            for (String string:strings
                 ) {
                System.out.println(string);
            }
    
            //将text替换成practice
            System.out.println(str.replace("text","practice"));
    
            //在text前插入easy
            System.out.println(str.replace("text","easy text"));
    
            //将每个单词首字母大写
            for(int i = 0;i < strings.length;i++){
                Character first = strings[i].charAt(0);
                //把首字母大写 基本类型调用时要用包装类
                char upfirst = first.toUpperCase(first);
                String newstrings = upfirst + strings[i].substring(1);
                System.out.println(newstrings);
    
            }
        }
    }
    

可变字符串

StringBuffer

可变长字符串,JDK1.0提供,运行效率慢、线程安全

相当于带了一个缓冲区

public class Demo07 {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        //append()向缓冲区追加字符串
        sb.append("java");
        System.out.println(sb.toString());   //java
        sb.append("编程语言");
        System.out.println(sb.toString());   //java编程语言

        //insert()添加 可以在某个位置添加
        sb.insert(0,"最前面");    //在第0个前面添加
        System.out.println(sb.toString());

        //replace()替换 可以指定位置
        sb.replace(0,3,"hello"); //把第0个到第2个替换成hello  (含头不含尾 不换3号位)
        System.out.println(sb.toString());

        //delete()删除 可以指定位置
        sb.delete(0,5);   //把第0个到第4个删除  (含头不含尾 不删5号位)
        System.out.println(sb.toString());

        //清空缓冲区
        sb.delete(0,sb.length());
        System.out.println(sb.length());  //0
    }
}
StringBuilder

StringBuilder和StringBuffer方法一样

可变长字符串,JDK1.5提供,运行效率快,线程不安全

  • 验证StringBuilder效率高于String
public class Demo08 {
    public static void main(String[] args) {
        //验证StringBuilder效率高于String
        //记录开始时间
        long start = System.currentTimeMillis();
        String string = "";
        //自字符串拼接
        for (int i = 0; i < 9999; i++) {
            string += i;
        }
        //System.out.println(string);
        //记录结束时间
        long end = System.currentTimeMillis();

        System.out.println("用时:" + (end - start));     //389
        System.out.println("-------------------------------");

        //开始时间
        start = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 99999; i++) {
            stringBuilder.append(i);
        }
        //System.out.println(stringBuilder.toString());

        //结束时间
        end = System.currentTimeMillis();

        System.out.println("用时:" + (end - start));     //11
    }
}
这两种和String的区别

1、效率比String高

2、比String节省内存

BigDecimal类

  • 思考:以下程序输出结果是多少?

public class Demo09 {
public static void main(String[] args) {
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1 - d2); //0.09999999999999998

      double result = (1.4 - 0.5) / 0.9;
      System.out.println(result);      //0.9999999999999999
  }

}


原因:`double`、`float`类型存储的是近似值,不是准确值,在经过计算后可能会出现**极小**的误差,在允许范围内可以

- 所以需要精度要求非常高的类来解决这个问题,`BigDecimal`是精确存储可以解决这个问题

- 位置:java.math包中

- 作用:精确计算浮点数

- 创建方式:`BigDecimal bD = new BigDecimal(“1.0”);`   

- 传入的参数一定要用字符串表示,外加`""`

- 方法:

1、加法:BigDecimal add(BigDecimal bd);

2、减法:BigDecimal subtract(BigDecimal bd);

3、乘法:BigDecimal multiply(BigDecimal bd);

4、除法:BigDecimal divide(BigDecimal divisor, int scale, RoundingMode mode)

- 参数scale:指定精确到小数后几位

- 参数mode:指定小数部分的取舍模式,通常采用四舍五入(`BigDecimal.ROUND_HALF_UP`)

- 除法如果除不尽且没有给**保留位数**和**取舍模式**会报错

```java
public class Demo09 {
    public static void main(String[] args) {
        double d1 = 1.0;
        double d2 = 0.9;
        System.out.println(d1 - d2);//0.09999999999999998

        //面试题
        double result = (1.4 - 0.5) / 0.9;
        System.out.println(result);//0.9999999999999999

        //BigDecimal大浮点数的精确计算
        BigDecimal bd1 = new BigDecimal("1.0");
        BigDecimal bd2 = new BigDecimal("0.9");
        BigDecimal bd3 = new BigDecimal("0.2");

        //类做运算要调用对应方法

        //减法
        BigDecimal r1 = bd1.subtract(bd2);
        System.out.println(r1);     //0.1
        //加法
        BigDecimal r2 = bd1.add(bd2);
        System.out.println(r2);     //1.9
        //乘法
        BigDecimal r3 = bd1.multiply(bd2);
        System.out.println(r3);     //0.90
        //除法
        BigDecimal r4 = bd1.divide(bd3);
        System.out.println(r4);     //5

        //除不尽可以写保留几位小数 2表示保留两位小数  BigDecimal.ROUND_HALF_UP表示四舍五入
        BigDecimal r5 = bd1.divide(bd2,2,BigDecimal.ROUND_HALF_UP);
        System.out.println(r5);    //1.11
    }
}

Date类

  • Date表示特定的瞬间,精确到毫秒,Date类中的大部分方法都已经被Calendar类中的方法所取代

  • 时间单位

    • 1秒 = 1000毫秒
    • 1毫秒 = 1000微秒
    • 1微秒 = 1000纳秒
  • 还可以使用的构造方法:

    1、Date();

    分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)

    2、Date(long date);

    分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元”,即1970年1月1日00:00:00 GMT)以来指定毫秒数

public class Demo10 {
    public static void main(String[] args) {
        //创建Date对象
        //今天
        Date date1 = new Date();
        System.out.println(date1);
        //划掉的代表过时方法
        System.out.println(date1.toLocaleString());//2020-10-8 8:44:22

        //昨天
        Date date2 = new Date(date1.getTime() - 60 * 60 * 24 * 1000);//毫秒数
        System.out.println(date2.toLocaleString());//2020-10-8 8:46:20

        //方法before、after 
        System.out.println(date1.after(date2));    //1是在2之后吗   true
        System.out.println(date1.before(date2));  //false

        //compareTo()  比较  结果为 -1  0  1
        int d = date1.compareTo(date2);      //date1比date2时间考前 所以为1  反之-1  相同为0
        System.out.println(d);               //1 

        //equals()  比较是否相等
        System.out.println(date1.equals(date2));   //false
    }
}

Calender类

  • Calendar提供了获取或设置各种日历字段的方法

  • 构造方法:

    • protected Calendar();由于修饰符是protected,所以无法直接创建该对象
  • 其他方法

    方法名说明
    static Calendar getInstance()使用默认时区和区域获得日历
    void set(int year,int month,int date,int hourofday,int minute,int second)设置日历的年、月、日、时、分、秒
    int get(int field)返回给定日历字段的值,如年、月、日等
    void setTime(Date date)用给定的Date设置此日历的时间,Date->Calendar
    Date getTime()返回一个Date表示此日历的时间,Calendar->Date
    void add(int field,int amount)按照日历的规则,给指定的字段添加或减少时间量
    long getTimeInMillies()毫秒为单位返回该日历的时间值
public class Demo11 {
    public static void main(String[] args) {
        //创建Calendar对象
        Calendar calendar = Calendar.getInstance();

        System.out.println(calendar.getTime().toLocaleString());//2020-10-8 20:00:51
        System.out.println(calendar.getTimeInMillis());//1603886451154

        //获取时间信息 get()
        int year = calendar.get(Calendar.YEAR);
        //0-11
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);//HOUR-12小时,HOUR_OF_DAY-24小时
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        System.out.println(year + "年" + (month + 1) + "月" + day + "日" + " " + hour + ":" + minute + ":" + second);
        //2020年10月8日 20:0:51

        //修改时间
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_MONTH, 3);
        System.out.println(instance.getTime().toLocaleString());//2020-10-3 20:00:51

        //add方法修改时间
        instance.add(Calendar.HOUR, 1);
        System.out.println(instance.getTime().toLocaleString());//2020-10-3 21:00:51

        //补充方法
        int actualMaximum = instance.getActualMaximum(Calendar.DAY_OF_MONTH); //当前月份最多几天
        int actualMinimum = instance.getActualMinimum(Calendar.DAY_OF_MONTH); //当前月份最少几天
        System.out.println(actualMaximum);//八月最大天数31
        System.out.println(actualMinimum);//八月最小天数1

    }
}

SimpleDateFormat类

  • SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类

  • 进行格式化(日期->文本)、解析(文本->日期)

  • 常用的时间模式字母

    字母日期或时间示例
    y2020
    M年中月份08
    d月中天数10
    H1天中小时数(0-23)22
    m分钟16
    s(小写)59
    S(大写)毫秒367
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo12 {
    public static void main(String[] args) throws ParseException {
        //创建SimpleDateFormat对象  y年 M月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
        //创建Date
        Date date = new Date();
        //格式化date(把日期转成字符串)
        String str = sdf.format(date);
        System.out.println(str);   //2020年10月9日 11:45:21

        //解析(把字符串转成日期)
        //  Date date2 = sdf.parse("1995/05/01");
        Date parse = sdf.parse("2020-05-01 12:06:36");//注意格式一定要与上面的pattern(时间模式)一致
        //不按pattern格式来会出现异常!!!!!
        System.out.println(parse);   //Fri May 01 12:06:36 CST 2020
    }
}

System类

  • System系统类,主要用于获取系统的属性数据和其他操作

  • 构造方法私有,不需要创建对象,可以直接用

  • 方法

    方法名说明
    static void arraycopy(…)复制数组
    static long currentTimeMillis()获取当前系统时间,返回的是毫秒值
    static void gc()建议JVM赶快启动回收器回收垃圾
    static void exit(int status)退出JVM,如果参数是0表示正常退出,非0表示异常退出
public class Demo13 {
    public static void main(String[] args) {
        //arraycopy()  数组的复制
        // (要复制的数组,从哪个位置开始复制,复制到哪里,从哪里开始放置复制的东西,复制长度)
        //src:原数组  srcPos:从哪个位置开始  dest:目标数组  destPos:目标数组的位置  length:复制的长度
        int[] arr1 = {20,18,15,8,35,26,45,90};
        int[] arr2 = new int[8];
        //System.arraycopy(arr1,0,arr2,0,arr1.length);
        System.arraycopy(arr1,4,arr2,0,4);
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
        //Arrays.copyOf(orginal,newLength)内部用的也是System.arraycopy()

        //获取当前系统时间 返回是毫秒数 可用于计时(记录开始时间结束时间然后相减)
        System.out.println(System.currentTimeMillis());

        //System.gc()  告诉垃圾回收器回收垃圾
        //具体例子见Object类finalize()

        //exit(int status)
        System.exit(0);  //退出JVM

        System.out.println("zzz");//不会执行 因为上面退出JVM了
    }
}

File类(具体详见I/O)

概述

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

构造方法

  • public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

常用方法

获取功能的方法
  • public String getAbsolutePath() :返回此File的绝对路径名字符串。
  • public String getPath() :将此File转换为路径名字符串。
  • public String getName() :返回由此File表示的文件或目录的名称。
  • public long length() :返回由此File表示的文件的长度。
绝对路径和相对路径
  • 绝对路径:从盘符开始的路径,这是一个完整的路径。
  • 相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
判断功能的方法
  • public boolean exists() :此File表示的文件或目录是否实际存在。
  • public boolean isDirectory() :此File表示的是否为目录。
  • public boolean isFile() :此File表示的是否为文件。
创建删除功能的方法
  • public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
  • public boolean delete() :删除由此File表示的文件或目录。
  • public boolean mkdir() :创建由此File表示的目录。
  • public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

目录的遍历

  • public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
  • public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

总结

  • 内部类:
    • 在一个类的内部再定义一个完整的类。
    • 成员内部类、静态内部类、局部内部类、匿名内部类
  • Object类:
    • 所有类的直接或间接父类,可存储任何对象
  • 包装类:
    • 基本数据类型所对应的引用数据类型,可以使Object统一所有数据
  • String类:
    • 字符串是常量,创建之后不可改变,字面值保存在字符串池中,可以共享
  • BigDecimal:
    • 可精确计算浮点数
  • Date:
    • 特定时间
  • Calendar:
    • 日历
  • SimpleDateFormat:
    • 格式化时间
  • System:
    • 系统类
  • File类:
    • 文件类
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值