(十)工具类设计,包装类,String类等概括

常用类


1.工具类的设计

2.单例模式
3.包装类
4.BigDecimal类
5.String
6.StringBuilder和StringBuffer类


1.工具类的设计

把很多的通用的方法集合在一起装到一个类中,这个类就叫做工具类

  • 工具类起名:XxxUtil,XxxTool等 such as:ArrayUtil,JDBCUtils
  • 工具类存在的包起名:util,utils,tool等

工具类如何设计?

两种设计

  • 公共静态方法
使用类名调用工具方法
构造器需要私有化,静态方法,防止工具类创建对象来调用静态方法
  • 单例模式
使用工具类的对象来调用工具方法,把工具类设计为单例模式(后讲)

工具类设计

/**
* 这是一个数组的工具类,包含了打印数组,排序等方法
 * e.g:
 * int[] arr=...
 * ArrayUtils.printArray(arr)
 * @author kent
 * @since 2021-01-22
 * @see "  "
* */
public class ArrayUtils {
    private ArrayUtils(){}   //私有构造方法,这样就可以防止实例被创建
    //定义static方法,用类名调用方法
    public static void printArray(){
        System.out.println("假装是数组的算法");
    }
    public static void sort(){
        System.out.println("排序");
    }
}


2.单例模式

设计模式:一套可以被反复使用的代码设计经验总结

单例设计模式(singleton):最常用、最简单的设计模式,单例的编写有N种写法

单例模式保证整个应用中某一类有且只有一个实例(对象)


2.1懒汉式

  • 私有化构造方法,事先创建好类的(static)一个对象

  • 提供一个公共静态方法(用于外界访问),在该方法中进行判断是否有对象,有返回预先创建好的对象,没有就new一个 ,

  • 其他方法可以不用static修饰

  • 调用

调用 类名.静态方法名(相当于一个对象)
调用方法  类名.静态方法名.方法
/*
*
* 懒汉模式   ( 存在线程安全 )
* */
public class AppSingleton {
    //要求:保持该类在系统中只有一个实例
    private static AppSingleton instance = null;

    //1.私有化构造方法
    private AppSingleton(){}

    //2.对外界提供统一的访问方式
    public static AppSingleton getInstance(){
        if (null == instance){
            instance =new AppSingleton();
        }
        return instance;
    }

    //3.把工具方法附载到该单例上
    public  void printArray(){
        System.out.println("数组");
    }

}


2.2饿汉式

  • 私有化构造方法(防止外界通过构造器创建新的工具类对象)
  • 提前创建好类的对象 new 类名()
  • 提供一个公共静态方法,用于返回自身对象
/*
*
* 饿汉模式
* */
public class AppSingleton01 {
    //要求:保持该类在系统中只有一个实例,提前创建(JVM加载AppSingleton01单例时已经被创建好了 )
    private static AppSingleton01 instance = new AppSingleton01();

    //1.私有化构造方法
    private AppSingleton01(){}

    //2.对外界提供统一的访问方式
    public static AppSingleton01 getInstance(){

        return instance;
    }

    //3.把工具方法附载到该单例上
    public  void printArray(){
        System.out.println("数组");
    }

}


3.包装类

包装类就是把基本数据类型封装到一个类中,让开发者更方便的操作基本类型

3.1八大基本类型包装类

byteshortintlongfloatdoublecharboolean
ByteShortIntegerLongFloatDoubleCharacterBoolean


常用转换方法

public class Test01 {
    public static void main(String[] args) {

         //常用方法
        //Integer -> int
        Integer i1 = new Integer("100");
        int a = i1.intValue();

        //int ->Integer
        //这种通过静态方法返回一个本类的对象 =>工厂方法
        //new Integer(int/String) =>valueOf(int /String)
        Integer i2 = Integer.valueOf(100);

        //Integer -> String
        Integer i3 = Integer.valueOf(300);
        System.out.println(i3.toString());

        //String ->Integer
        Integer i4 = Integer.valueOf("500");
        
        
        //String -> int
        int i = Integer.parseInt("100");

        //int ---> String
        String s = Integer.toString(200);

        /*
        *总结:
        * int <->String
        * Integer 桥梁 =>
        * int <-> Integer <-> String
        *
        * */

    }
}


3.2装箱和拆箱( Auto-Boxing和 Auto-UnBoxing)

  1. 装箱:基本数据类型 --> 包装类
  2. 拆箱:包装类 --> 基本数据类型
       //装箱  把基本数据类型 ->对应的包装类的过程
        Integer i1 = Integer.valueOf(10);
        Integer i2 = new Integer(10); //一般不用这个了,被淘汰

        //拆箱  把包装类对象 ->对于基本数据类型
        int t1 = i1.intValue();
        int t2 = i2.intValue();
  • 自动装箱:可把一个基本类型变量直接赋给对应的包装类变量。
  • 自动拆箱:可以把包装类对象直接赋给对应的基本数据类型变量。
所谓自动就是jvm自动帮我们转换了,调用了装箱与拆箱的方法
1.自动装箱
Integer i1 = 13;   
jvm实际调用 Integer i1 = Integer.valueOf(13)
    
2.自动拆箱
int i2 = i1; //  jvm实际调用 i1.intValue() 

思考?

Object obj =10;
/*
*  Integer i1 =10;   //自动装箱操作
*  Object obj =i1;   // 把子类对象赋值给父类变量 (父引子)
*/


3.3包装类的缓存设计

从性能上考虑,把常用数据存储到缓存区域,使用时不需要每次都创建新的对象,可以提高性能。

  • Byte、Short、Integer、Long:缓存范围[-128,127];
  • Character:缓存范围[0,127];

cache原理

在这里插入图片描述

个人理解:

Integer 中的 cache缓存机制是将范围为(-128,127)的值,提前与加载缓存,
当我们去初始化这个范围的值时(不用new),其实就已经存在了
.当超出这个范围的值时,就是相当于真正开辟(new)了一块空间.
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1 == i2);// false  new相当于new出了两块空间,肯定是不一样的

Integer i3 = Integer.valueOf(10);
Integer i4 = Integer.valueOf(10);
System.out.println(i3 == i4);// true

Integer i5 = 10; // 底层等价于
Integer i6 = 10;
System.out.println(i5 == i6);// true


4.BigDecimal类

float和double都不能表示精确的小数,使用BigDecimal类可以解决该问题

BigDecimal不能直接把赋值和运算操作,只能通过构造器传递数据,而且必须使用字符串类型的构造器

RoundingMode 舍入模式

  • RoundingMode.HALF_UP 四舍五入
  • RoundingMode.HALF_Down 四舍六入

例子:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Test01 {
    public static void main(String[] args) {

        System.out.println(0.01+0.09); //精度缺失

        //一定要使用字符串的构建方式
        BigDecimal b1 = new BigDecimal("0.01");
        BigDecimal b2 = new BigDecimal("0.09");
        //相加
        BigDecimal add = b1.add(b2);
        System.out.println(add);
        
        //相减
        BigDecimal b9 = new BigDecimal("0.01");
        BigDecimal b10 = new BigDecimal("0.09");
        BigDecimal subtract = b9.subtract(b10);
        System.out.println(subtract);

        //精度控制
        BigDecimal b3 = new BigDecimal("3.1418");
        BigDecimal b4 = new BigDecimal("2");
        //6.2836
        //multiply 乘法操作,保留两位小数(setScale 2),四舍五入(RoundingMode.HALF_UP)
        b3.multiply(b4).setScale(2, RoundingMode.HALF_UP);

        //除法
        BigDecimal b5 = new BigDecimal("10");
        BigDecimal b6 = new BigDecimal("3");
        b5.divide(b6).setScale(2, RoundingMode.HALF_UP);//3.33
    }
}


5.String

String类型表示字符串,在内存中是以字符数组的形式存在的

String是字符数组的包装类,并提供以只读的形式操作其包装的字符数组的方法。

String str = "ABCD"; 等价于 char[] cs = new char[]{'A','B','C','D'};


String对象是不可变的
,所以可以共享

  • 常量池
1.通过字面量创建的字符串分配在常量池中 字面量字符串是常量,值在创建之后是不能更改的
通过new操作创建的字符串分配在堆中,当String对象创建完毕之后,该对象的内容是不能改变的,一旦内容改变就会变成了一个新的对象
1.直接赋予字面量
    String str1 ="ABC";   //常量池
2.通过构造器创建
    String str2 = new String("ABC"); //堆中


5.1String对象的空值

1.表示引用为空(null)
String str1 = null; //没有初始化,没有分配内存空间

2.内容为空字符串
String str2 = ""   //已经初始化,分配内存空间,不过没有内容    


5.2字符串常用方法

  • 字符串比较

== 与equals的区别

  • ==:比较两个字符串引用内存地址是否相同
  • equals:比较两个字符串内容是否相等
 String str1 = "abc";
        String str2 = "abc";
        System.out.println(str1 ==str2);  //true 同样放在常量池,表示唯一引用同一地址

        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1.equals(s2));  // equals 重写后比较当前两个对象的内容是否相等
        System.out.println(str1 ==s1);  // str1在常量池中,new出来的s1在堆中

        //面试题
        String str3 = "" + "abc";
        String str4 = str1 + "";
        System.out.println(str1==str3); //true ,常量词中,允许字符串拼接,"+拼接了"abc" 还是等于"abc"
        System.out.println(str1 ==str4);//false , str1 + ""表示已经在堆中,地址不同

  • 判断一个字符串非空
public static boolean ifNull(String str){
        return str !=null && !"".equals(str.trim());
    }
  • 其他方法
public class Test04 {
    public static void main(String[] args) {
         String str = "小小罗nb";
         String str1 = "小月";
         String str2 = "小小罗NB";
         //length():返回字符串的个数
        System.out.println(str.length());  //4

        //char(int index):返回指定索引字符
        System.out.println(str.charAt(0)); //小

        //int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引位置
        System.out.println(str.indexOf("小")); //0

        //boolean equals(Object anObject) 比较内容是否相同
        System.out.println(str.equals(str1)); //false

        //boolean equalsIgnoreCase(String anotherString) 忽略虑大小写,比较内容是否相同
        System.out.println(str.equalsIgnoreCase(str2)); //true

        //String toUpperCase() 把当前字符串转换为大写
        System.out.println(str.toUpperCase()); //小小罗NB

        //String toLowerCase() 把当前字符串转换为小写
        System.out.println(str2.toLowerCase()); //小小罗nb

        //String substring(int beginIndex):从指定位置开始截取字符串
        System.out.println(str.substring(2)); //罗nb

        //String substring(int beginIndex, int endIndex):截取指定区域的字符串
        System.out.println(str.substring(0, 2)); //小小
        注意:
        在java的api中看到类似以下的参数,基本都是含头不含尾
        1.beginIndex ,endIndex
        2.begin,end
        3.fromIndex,toIndex
        4.from,to 等

    }
}
String操作()
1.split(用于分割)
String letStr = "ABCDEFGHJ";
String[] arr = letStr.split(""); //传空引号隔开
for(String item:arr){
 System.out.println(item);
}
2.测试字符串是否包含另外一个字符串
String str = "helloworld";
System.out.println(str.contains("hello"));


6.StringBuilder和StringBuffer类

StringBuffer和StringBuilder都表示可变的字符串,可以对字符串进行拼接

开发中建议使用StringBuilder(线程不安全,但是性能较高)

如果事先知道需要拼接多少个字符,可以在创建StringBuilder对象时指定字符数组容量
    StringBuilder re = new StringBuilder(17);
使用append方法在原字符串后面进行拼接
    re.append("小轩").append(520).append("小月");

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值