shanX
文章31
标签17
分类9
JAVA-常用类

JAVA-常用类

常用类

内部类

成员内部类、静态内部类、局部内部类、匿名内部类

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

特点:

  • 编译之后可生成独立的字节码文件
  • 内部类可直接访问外部类私有成员,而不破坏封装
  • 可为外部类提供必要的内部功能组件
Outer$Inner.class` `Outer.class
// 身体
class Body{
  // 头部
  class Header{
    // 也会生成class文件
  }
}

成员内部类

  • 在类的内部定义,与实例变量、实例方法同级别的类
  • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
  • 当外部类、内部类存在重名属性时,会优先访问内部类属性
  • 成员内部类里不能定义静态成员、可以包含静态常量(final)
// 外部类
public class Outer{
  //实例变量
  private String name = "张三";
  private int age = 20;
  //内部类
  class Inner{
    private String address = "北京";
    private String phone = "110";
    private String name = "李四";

    //方法
    public void show(){
      //打印外部类属性 此时有重名属性name
      sout(Outer.this.name); // 张三
      sout(age);
      //打印内部类中的属性
      sout(name); // 李四
      sout(address);
      sout(phone);
    }
  }
}

// 测试类
public class Test{
  psvm(String[] args){
    // 创建外部类对象
    Outer outer = new Outer();
    // 创建内部类对象
    Inner inner = outer.new Inner();

    //一步到位
    Inner inner = new Outer(.new Inner();

    inner.show();
  }
}

静态内部类

  • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
// 外部类
public class Outer{
  //实例变量
  private String name = "xxx";
  private int age = 20;

  // 静态内部类,和外部类相同
  static class Inner{
    private String address = "上海";
    private String phone = "111";
    // 静态成员
    private static int count = 1000;

    //方法
    public void show(){
      // 调用外部类的属性
      // 1. 先创建外部类对象
      Outer outer = new Outer();
      // 2. 调用外部类对象的属性
      sout(outer.name);
      sout(outer.age);
      // 调用静态内部类的属性和方法
      sout(address);
      sout(phone);
      // 调用静态内部类的静态属性
      sout(Inner.count);
    }
  }
}

// 测试类
public class Test{
  psvm(String[] args){
    // 直接创建静态内部类对象
    Outer.Inner inner = new Outer.Inner();

    inner.show();
  }
}

局部内部类

  • 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为 final
  • 限制类的使用范围
// 外部类
public class Outer{
  //实例变量
  private String name = "刘德华";
  private int age = 35;

  //方法
  public void show(){
    // 定义局部变量
    String address = "sz";

    // 局部内部类:注意不能加任何访问修饰符
    class Inner{
      private String phone = "11234";
      private String email = "ldh@qq.com";

      public void show2(){
        // 访问外部类的属性
        sout(name); // 相当于 Outer.this.name
        sout(age);
        // 访问内部类的属性
        sout(this.phone);
        sout(this.email);

        // 访问局部变量 jdk1.7要求必须常量final、jdk1.8自动添加final

      }
    }
    // 创建局部内部类对象
    Inner inner = new Inner();
    inner.show2();
  }
}

// 测试类
public class Test{
  psvm(String[] args){
    // 创建外部类对象
    Outer outer = new Outer();

    outer.show();
  }
}

匿名内部类

  • 没有类名的局部内部类(一切特征都与局部内部类相同)
  • 必须继承一个父类或者实现一个接口
  • 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
  • 优点:减少代码量
  • 缺点可读性较差
// 使用匿名内部类优化(相当于创建了一个局部内部类)
Usb usb = new Usb(){ // Usb为一个接口
  @Override
  public void service(){
    sout("连接电脑成功,fan开始工作")
  }
};
usb.service();

Object 类

  1. 超类、基类,所有类的直接或间接父类,位于继承树的最顶层
  2. 任何类,如没有书写 extends 显示继承某个类,都默认直接继承 Object 类,否则为间接继承
  3. Object 类中所定义的方法,是所有对象都具备的方法
  4. Object 类型可以存储任何对象
    1. 作为参数,可接受任何对象
    2. 作为返回值,可返回任何对象

getClass 类

  1. public final Class<?> getClass(){}

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

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

// 判断s1 和 s2是不是同一个类型
Class class1 = s1.getClass();
Class class2 = s2.getClass();
// getClass返回 class类型

hashcode 类

  1. public int hashCode(){}
  2. 返回该对象的哈希码值
  3. 哈希值根据对象的地址或字符串或数字使用 hash 算法计算出来的 int 类型的值
  4. 一般情况下相同对象返回相同哈希码
s1.hashCode();
s2.hashCode();
// 自然不同  hashcode s1 != s2
Student s3 = s1;
s3.hashCode();
// s3的hashCode与s1相同,将s1赋给s3

toString 类

  1. public String toSring(){}
  2. 返回该对象的字符串表示(表现形式)
  3. 可以根据程序需求覆盖该方法,如:展示对象各个属性值
sout(s1.toString()); // 直接打印包+类名+哈希值

// 重写 快捷键 alt + Ins
@override
public String toString(){
  return "Student [name = " + name + ", age = " + age + "]";
}

equals()类

  1. public boolean equals(Object obj){}
  2. 默认实现为(this == obj), 比较两个对象地址是否相同
  3. 可进行覆盖,比较两个对象的内容是否相同
System.out.println(s1.equals(s2)); //false
Sstudent s3 = s1;
System.out.println(s1.equals(s3)); //true

Student eq1 = new Student("xm", 11);
Student eq2 = new Student("xm", 11);
System.out.println(eq1.equals(eq2)); //false,地址不同

​ 重写 equals()方法:

Entity中:
// 重写 改变其比较内容
/*
步骤  1. 比较两个应用是否指向同一个对象
     2. 判断obj是否为null
     3. 判断两个引用只想的实际对象类型是否一致
     4. 强制类型转换
     5. 依次比较各个属性值是否相同
*/
@override
public boolean equals(Object obj){
  // 1.
  if(this == obj){
    return true;
  }
  // 2.
  if(obj == null){
    return false;
  }
  // 3.
  // if(this.getClass() == obj.getClass()){
  //
  // }
  // instanceof 判断对象是否是某种类型
  if(obj instanceof Student){
    // 4.强制类型转换
    Student s = (Student)obj;
    // 5. 比较属性
    if(this.name.equals(s.getName()) && this.age == s.getAge()){
      return true;
    }
  }
  return false;
}

finalize()方法

  1. 当对象被判定为垃圾对象时,由 JVM 自动调用此方法,用以标记垃圾对象,进入回收队列
  2. 垃圾对象:没有有效引用指向此对象时,为垃圾对象
  3. 垃圾回收:由 gc 销毁垃圾对象,释放数据存储空间
  4. 自动回收机制:JVM 的内存耗尽,一次性回收所有垃圾对象
  5. 手动回收机制:使用System.gc();通知 JVM 执行垃圾回收
finalize默认为空,重写方法:
@Override
protected void finalize() throws Throwable{
  sout(this.name + "对象被回收了");
}

Student s1 = new Student("aaa", 1);
new Student("aaa", 1);
//手动告诉JVM进行回收;
System.gc();
System.out.println("回收垃圾");

包装类

  1. 基本数据类型所对应的引用数据类型
  2. Object 可统一所有数据,包装类的默认值是 null
基本数据类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character

类型转换与装箱、拆箱

  1. 8 种包装类提供不用类型间的转换方式
    1. Number 父类中提供的 6 个共性方法
    2. parseXXX( )静态方法
    3. valueOf( )静态方法
  2. 注意:需保证类型兼容,否则抛出NumberFormatException异常
public static void main(String[] args) {
        // 装箱, 基本类型 → 引用类型
        // 基本类型
        int num1 = 18;
        // 使用Integer类创建对象
        Integer integer1 = new Integer(num1);
        Integer integer2 = Integer.valueOf(num1);

        System.out.println("装箱");
        System.out.println(integer1);
        System.out.println(integer2);

        // 拆箱, 引用类型 → 基本类型
        Integer integer3 = new Integer(100);
        int num2 = integer3.intValue();

        System.out.println("拆箱");
        System.out.println(num2);

        //↑ JDK1.5 之前,JDK1.5之后自动装箱和拆箱
        int age = 30;
        //自动装箱
        Integer integer4 = age;
        System.out.println("自动装箱");
        System.out.println(integer4);
        //自动拆箱
        int age2 = integer4;

        System.out.println("自动拆箱");
        System.out.println(age2);
        System.out.println("---------------------------------------");
        //基本类型和字符串之间的转换
        //基本类型转换为字符串
        // 基本类型和字符串之间转换
        // 1. 基本类型转成字符串
        int n1 = 100;
        // 1.1 使用+号
        String s1 = n1 + "";
        // 1.2 使用Integer中的toString()方法
        String s2 = Integer.toString(n1,2);
        System.out.println(s2);
       //String s2 = Integer.toString(n1, x); // x为进制要求

        // 2. 字符串转成基本类型
        String str = "150";
        // 使用Integer.parseXXX();
        int n2 = Integer.parseInt(str);
        System.out.println(n2);

        // boolean 字符串形式转成基本类型,"true" ---> true 非“true ———> false
        String str2 = "true";
        boolean b1 = Boolean.parseBoolean(str2);
        System.out.println(b1);
    }

整数缓冲区

  1. Java 预先创建了 256 个常用的证书包装类型对象
  2. 在实际应用当中,对已创建的对象进行复用
  public static void main(String[] args) {
        // 面试题
        Integer integer1 = new Integer(100);
        Integer integer2 = new Integer(100);
        System.out.println(integer1 == integer2); // false

        Integer integer3 =  Integer.valueOf(100);// 自动装箱
        // 相当于调用 Integer.valueOf(100);
        Integer integer4 = Integer.valueOf(100);
        System.out.println(integer3 == integer4); // true

        Integer integer5 = Integer.valueOf(200);// 自动装箱
        Integer integer6 = Integer.valueOf(200);
        System.out.println(integer5 == integer6); // false

        // 因为缓存区数组 [-128, 127] 在这之内地址一样
    }

String 类

  1. 字符串是 final 修饰的常量,创建之后不可改变
  2. 字符串字面值存储在字符串池中,可以共享
  3. String s = "Hello";产生一个对象,字符串池中存储
  4. String s = new String("Hello"); 产生两个对象,堆、池各一个
public static void main(String[] args) {

        // 1. length(); 返回字符串长度
        // 2. charAt(int index); 返回某个位置的字符
        // 3. contains(String str); 判断是否包含某个字符串

        String content = "java是最好的语言, java no1";
        System.out.println(content.length()); // 10
        System.out.println(content.charAt(content.length() - 1)); // 言
        System.out.println(content.contains("java")); // true

        // 4. toCharArray(); 返回字符串对应数组
        // 5. indexOf(); 返回子字符串首次出现的位置
        // 6. lastIndexOf(); 返回字符串最后一次出现的位置

        System.out.println(content.toCharArray());
        System.out.println(content.indexOf("java")); // 0
        System.out.println(content.indexOf("java", 4)); // 从索引4开始找 返回12
        System.out.println(content.lastIndexOf("java")); // 12

        // 7. trim(); //去掉字符串前后空格
        // 8. toUpperCase(); toLowerCase(); 转换大小写
        // 9. endWith(str); startWith(str);  判断是否以str 结尾、开头

        String ct = " hello world ";
        System.out.println(ct.trim()); // "hello world"
        System.out.println(ct.toUpperCase()); // HELLO WORLD
        System.out.println(ct.toLowerCase()); // hello world
        System.out.println(ct.endsWith("world")); // true
        System.out.println(ct.startsWith("hello")); // true

        // 10. replace(char old, char new); 用心的字符或字符串替换旧的字符或字符串
        // 11. split(); 对字符串拆分

        System.out.println(content.replace("java", "python")); // php是最好的语言, php no1

        String say = "java is the best language";
        String[] arr = say.split(" "); // "[ ,]+" 表示空格 逗号切分 +号表示切分可以多个 比如多个空格
        System.out.println(arr.length); // 5
        for (String string : arr) {
            System.out.println(string);
        }
        // 打印出
        //java
        //is
        //the
        //best
        //language

        // 补充两个equals/compareTo();比较大小
        String s1 = "hello";
        String s2 = "HELLO";
        System.out.println(s1.equalsIgnoreCase(s2));// 忽略大小写比较true

        // compareTo(); 两字符不同时比较字符字典序的ascii码
        // 字符相同时比较长度 返回差值

    }

String 常用方法

  1. length(); 返回字符串长度;
  2. charAt(int index); 返回某个位置的字符;
  3. contains(String str); 判断是否包含某个字符串;
  4. toCharArray(); 返回字符串对应数组;
  5. indexOf(); 返回子字符串首次出现的位置;
  6. lastIndexOf(); 返回字符串最后一次出现的位置;
  7. trim(); //去掉字符串前后空格;
  8. toUpperCase(); toLowerCase(); 转换大小写;
  9. endWith(str); startWith(str); 判断是否以 str 结尾、开头;
  10. replace(char old, char new); 用心的字符或字符串替换旧的字符或字符串;
  11. split(); 对字符串拆分;

案例演示

需求:

  1. 已知 String str = “this is a text”;
  2. 将 str 中的单词单独获取
  3. 将 str 中的 text 替换成 practice
  4. 在 text 前面插入一个 easy
  5. 将每个单词的首字母改为大写
public static void main(String[] args) {
//        已知String str = "this is a text";
//        将str中的单词单独获取
//        将str中的text替换成practice
//        在text前面插入一个easy
//        将每个单词的首字母改为大写

        String str = "this is a text";
        String[] arr = str.split(" ");
        for (String s : arr) {
            System.out.println(s);
        }


        str = str.replace("text", "practice");
        System.out.println(str);

        str =  str.replace("practice", "easy practice");
        System.out.println(str);

        for (int i = 0; i < arr.length; i++) {
            char first = arr[i].charAt(0);
            char upperfirst = Character.toUpperCase(first);
            String newstr = upperfirst + arr[i].substring(1);
            System.out.println(newstr);

        }
    }

StringBuffer 和 StringBuilder

  1. StringBuffer : 可变长字符串,运行效率慢、线程安全
  2. StringBuilder : 可边长字符串、运行快、线程不安全

效率都比 String 高且节省内存

        StringBuffer sb = new StringBuffer();
        sb.append("java世界第一");
        System.out.println(sb.toString());
        sb.append("java真香");
        System.out.println(sb.toString());
        sb.append("java不错");
        System.out.println(sb.toString());
        sb.insert(0,"我在最前面");
        System.out.println(sb.toString());
        sb.replace(0,5,"hello");
        System.out.println(sb.toString());
        sb.delete(0,5);
        System.out.println(sb.toString());
        sb.delete(0,sb.length());
        System.out.println("delete" + sb.toString());

测试效率:

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String str = "";
        for (int i = 0; i < 99999; i++) {
            str+=i;
        }

        long end = System.currentTimeMillis();

        System.out.println((float) (end-start)/1000 + "s");


        long start2 = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer("");
        for (int i = 0; i < 99999; i++) {
            sb.append(i);
        }

        long end2 = System.currentTimeMillis();

        System.out.println(end2-start2 + "ms");

        long start3 = System.currentTimeMillis();
        StringBuilder sbu = new StringBuilder("");
        for (int i = 0; i < 99999; i++) {
            sbu.append(i);
        }

        long end3 = System.currentTimeMillis();

        System.out.println(end3-start3 + "ms");

    }

输出结果:
18.49s
10ms
0ms

可见效率差距

BigDecimal 类

  1. 位置 java.math 包中

  2. 作用 精确计算浮点数

  3. 创建方式 BigDecimal bd = new BigDecimal("1.0");

    ```java
    public static void main(String[] args) {

        double d1 = 1.0;
        double d2 = 0.9;
        System.out.println("d1-d2=" + (d1-d2));
    
        double res = (1.4-0.5)/0.9;
        System.out.println("result=" + res);
    
       BigDecimal bd1 = new BigDecimal("1.0");
       BigDecimal bd2 = new BigDecimal("0.9");

       BigDecimal bdres1 = bd1.add(bd2); //加
       BigDecimal bdres2 = bd1.subtract(bd2); //减
       BigDecimal bdres3 = bd1.multiply(bd2); //乘
       BigDecimal bdres4 =
           bd1.divide(bd2,2,BigDecimal.ROUND_HALF_UP); //除
   // bd1.divide(除数,小数精确到几位,BigDecimal.ROUND_HALF_UP=四舍五入);
       System.out.println("加="+bdres1+"\n减="+bdres2+"\n乘="+bdres3+"\n除="+bdres4);
   }

```java
d1-d2=0.09999999999999998
result=0.9999999999999999
加=1.9
减=0.1
乘=0.90
除=1.11

时间-Date 类

  1. Date 表示特定的瞬间,精确到毫秒。Date 类中的大部分方法都已经被 Calendar 类中的方法所取代; ( 时间单位:1s = 1,000ms = 1,000,000 μs = 1,000,000,000 = ns; )
public static void main(String[] args) {
        Date date1 = new Date();
        System.out.println(date1.toString());
        System.out.println(date1.toLocaleString());

        //昨天
        Date date2 = new Date(date1.getTime() - (60*60*24*1000));
        System.out.println(date2.toLocaleString());


        //方法after before
        boolean b1 = date1.after(date2);
        System.out.println(b1);

        boolean b2 = date1.before(date2);
        System.out.println(b2);


        //比较compareTo(),比较毫秒值
        int d1 = date1.compareTo(date2);
        System.out.println(d1);

        int d2 = date1.compareTo(date1);
        System.out.println(d2);

        //比较是否相等
        boolean b3 = date1.equals(date2);
        System.out.println(b3);

    }

时间-Calendar 类

  1. Calendar 提供了获取或设置各种日历字段的方法
  2. 构造方法 protected Calendar(); 由于是 protected 所以无法直接创建
  3. 其他方法
方法名 说明
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 getTime() 返回一个 date 表示此日历的时间
void add(int field, int amount) 按照日历的规则,给指定字段添加或减少时间量
long getTimeInMilles() 毫秒为单位返回该日历的时间值
public static void main(String[] args) {
        //创建Calendar对象
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.getTime().toString());
        System.out.println(calendar.getTimeInMillis());

        //获取时间信息
        //获取年
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int date = calendar.get(Calendar.DATE);
        int hour = calendar.get(Calendar.HOUR); //12时制
        int hour2 = calendar.get(Calendar.HOUR_OF_DAY);//24时制
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        String[] arr = {"日", "一", "二", "三", "四", "五", "六"};
        String week2 = arr[week-1];
        System.out.println(year + "/" + (month+1) + "/" + date  + "-" + hour + "("+ hour2 +")"  + ":" + minute + ":" + second + "-[ 星期" + week2 + "]");

        //修改时间
        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(Calendar.DAY_OF_MONTH, 5);
        System.out.println(calendar1.getTime().toLocaleString());

        //add方法修改时间
        calendar1.add(Calendar.HOUR, 1);
        System.out.println(calendar1.getTime().toLocaleString());

        //补充方法
        int max = calendar1.getActualMaximum(Calendar.DAY_OF_MONTH); //本月最大多少天
        int min =  calendar1.getActualMinimum(Calendar.DAY_OF_MONTH);//本月最小多少天?
        System.out.println(max);
        System.out.println(min);

        calendar1.add(Calendar.MONTH, 1);
        System.out.println(calendar1.getTime().toLocaleString());

        int max2 = calendar1.getActualMaximum(Calendar.DAY_OF_MONTH); //本月最大多少天
        int min2 =  calendar1.getActualMinimum(Calendar.DAY_OF_MONTH);//本月最小多少天?
        System.out.println(max2);
        System.out.println(min2);

    }
Tue Apr 06 21:25:51 CST 2021
1617715551128
2021/4/6-9(21):25:51-[星期二]
2021-4-5 21:25:51
2021-4-5 22:25:51
30
1
2021-5-5 22:25:51
31
1

SimpleDateFormat 类

  1. SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类
  2. 进行格式化(日期 → 文本)、解析(文本 → 日期)
  3. 常用的时间模式字母
字母 日期或时间 示例
y 2019
08 年中月份 08
d 月中天数 10
H 一天中小时(0-23) 22
m 分钟 16
s 59
S 毫秒 356
 public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");

        Date date = new Date();
        String str = sdf.format(date);
        System.out.println(str);

        Date date2 = sdf.parse("1990/05/01");
        System.out.println(date2);
    }

System 类

主要用于获取系统的属性数据和其他操作,构造方法私有的

方法名 说明
static void arraycopy(…) 复制数组
static long currentTimeMillis(); 获取当前系统时间,返回毫秒值
static void gc(); 建议 jvm 赶快启动垃圾回收期器回收垃圾
static void exit(int status); 退出 jvm 如果参数是 0 表示正常退出 jvm 非 0 表示异常退出
public static void main(String[] args) {
        // arrcopy 数组的复制
        // src: 源数组
        // srcPos: 从哪个位置开始复制 0
        // dest: 目标数组
        // destPos: 目标数组的位置
        // length: 复制的长度
        int[] arr = {20, 10, 15, 8, 35, 26, 45, 90};
        int[] targetarr = new int[8];

        System.arraycopy(arr, 4, targetarr, 6,2);
        System.out.println(Arrays.toString(targetarr));

        //Arrays.copyOf()底层源码实现方式依旧为arraycopy
        int[] targetarr2 = Arrays.copyOf(arr,6);
        System.out.println(Arrays.toString(targetarr2));

        //退出JVM,下面的代码不再执行
        System.exit(0);
        System.out.println("程序结束了···········");
    }
本文作者:shanX
本文链接:https://rhymexmove.github.io/2021/04/06/e3cec34b39ef/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可