15Java常用类(数组工具类Arrays)基本类型包装类(Integer类)正则表达式String的split(String regex)和replaceAll(String regex, (代码片

Posted shawnyue-08

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15Java常用类(数组工具类Arrays)基本类型包装类(Integer类)正则表达式String的split(String regex)和replaceAll(String regex, (代码片相关的知识,希望对你有一定的参考价值。

Arrays类

Arrays类概述

  • 针对数组进行操作的工具类
  • 提供了排序,查找等功能

Arrays类常用方法

toString()方法

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/1 14:39
 */
public class MyTest {
    public static void main(String[] args) {
        byte[] arr1 = {1, 2, 3, 4, 5};
        short[] arr2 = {1, 2, 3, 4, 5};
        int[] arr3 = {1, 2, 3, 4, 5};
        long[] arr4 = {2L, 3L, 4L, 5L};
        char[] arr5 = {‘A‘, ‘B‘, ‘C‘, ‘D‘};
        boolean[] arr6 = {true, false};
        float[] arr7 = {0.7f, 1.9f};
        double[] arr8 = {0.2, 0.3};
        Object[] arr9 = {new Object(), new Object()};
        System.out.println(Arrays.toString(arr1));
        System.out.println(Arrays.toString(arr2));
        System.out.println(Arrays.toString(arr3));
        System.out.println(Arrays.toString(arr4));
        System.out.println(Arrays.toString(arr5));
        System.out.println(Arrays.toString(arr6));
        System.out.println(Arrays.toString(arr7));
        System.out.println(Arrays.toString(arr8));
        System.out.println(Arrays.toString(arr9));
    }
}

toString()方法的源码

public static String toString(int[] a) {
    if (a == null)
        return "null";
    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";

    StringBuilder b = new StringBuilder();
    b.append(‘[‘);
    for (int i = 0; ; i++) {
        b.append(a[i]);
        if (i == iMax)
            return b.append(‘]‘).toString();
        b.append(", ");
    }
}

sort()方法(七种基本数据类型(除了boolean) + 引用类型)

package org.westos.demo1;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author lwj
 * @date 2020/5/1 14:47
 */
public class MyDemo {
    public static void main(String[] args) {
        int[] arr = {13, 12, 23, 15, 47};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        //[12, 13, 15, 23, 47]

        double[] arr1 = {12.3, 11.9, 13.7, 22.1, 0.9};
        Arrays.sort(arr1);
        System.out.println(Arrays.toString(arr1));
        //[0.9, 11.9, 12.3, 13.7, 22.1]

        short[] arr2 = {12, 13, 1, 34, 11, 22};
        Arrays.sort(arr2, 2, 6);
        System.out.println(Arrays.toString(arr2));
        //[12, 13, 1, 11, 22, 34]

        //默认是从小到大排列,如果想要从大到小排列,必须是引用类型 + 比较器
        Integer[] arr3 = {13, 12, 23, 15, 47};
        Arrays.sort(arr3, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        System.out.println(Arrays.toString(arr3));
        //[12, 13, 15, 23, 47]

        Double[] arr4 = {12.3, 11.9, 13.7, 22.1, 0.9};
        Arrays.sort(arr4, (o1, o2) -> (int)(o2 - o1));
        System.out.println(Arrays.toString(arr4));
        //[22.1, 13.7, 12.3, 11.9, 0.9]
        //从大到小排序
    }
}

内部是使用快速排序,默认从小到大。

binarySearch()方法

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/1 14:51
 */
public class Test {
    public static void main(String[] args) {
        int[] arr = {12, 13, 14, 15, 16};
        int key = 12;
        int index = Arrays.binarySearch(arr, key);
        System.out.println("key的在数组中的索引为" + index);
        //key的在数组中的索引为0
    }
}

binarySearch()方法的源码

public static int binarySearch(int[] a, int key) {
    return binarySearch0(a, 0, a.length, key);
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = a[mid];

        if (midVal < key)
            low = mid + 1;
        else if (midVal > key)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}

equals()方法 和 toString()方法参数一致(8种基本数据类型 + 引用数据类型)

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/1 14:53
 */
public class Demo {
    public static void main(String[] args) {
        int[] arr1 = {12, 13, 11, 23};
        int[] arr2 = {12, 11, 13, 23};
        boolean equals = Arrays.equals(arr1, arr2);
        System.out.println(equals);
        //false
        //Arrays.equals()方法,两个数组的对应索引的元素相等,两个数组才可以说相等
    }
}

equals()方法的源码

public static boolean equals(int[] a, int[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;

    int length = a.length;
    if (a2.length != length)
        return false;

    for (int i=0; i<length; i++)
        if (a[i] != a2[i])
            return false;

    return true;
}

copyOf()方法

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/1 16:50
 */
public class MyTest2 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int[] value = Arrays.copyOf(arr, 10);
        System.out.println(value.length);
        //10
        System.out.println(Arrays.toString(value));
        //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
		
        
        int[] copy = Arrays.copyOf(arr, 3);
        System.out.println(copy.length);
        //3
        System.out.println(Arrays.toString(copy));
        //[1, 2, 3]
    }
}

源码

public static int[] copyOf(int[] original, int newLength) {
    int[] copy = new int[newLength];
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 
// 将指定源数组从指定位置复制到目标数组的指定位置。  
package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/2 9:39
 */
public class MyDemo2 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
        int[] array = new int[10];
        System.arraycopy(arr, 0, array, 0, arr.length);
        System.out.println(Arrays.toString(array));
        //[1, 2, 3, 4, 5, 6, 7, 8, 0, 0]
    }
}

copyOfRange()方法

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/2 9:42
 */
public class Test2 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6};
        int[] copy = Arrays.copyOfRange(arr, 1, 4);
        //[1, 4)
        System.out.println(Arrays.toString(copy));
        //[2, 3, 4]
    }
}

基本类型的包装类

概述

基本数据类型 引用数据类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Integer的基本用法

三个基本方法和两个基本属性

Integer.toBinaryString()
Integer.toOctalString()
Integer.toHexString()
Integer.MIN_VALUE
Integer.MAX_VALUE
package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 12:05
 */
public class MyDemo {
    public static void main(String[] args) {
        int num = 100;
        //将整数转为二进制、八进制、十六进制
        String s = Integer.toBinaryString(num);
        String s1 = Integer.toOctalString(num);
        String s2 = Integer.toHexString(num);
        System.out.println(s);
        //1100100
        System.out.println(s1);
        //144 = 64 + 32 + 4 = 100
        System.out.println(s2);
        //64 = 16 * 6 + 4 = 100

        Object o = new Object();
        System.out.println(o.toString());
        /*public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }*/

        //判断一个数是否在int的范围内
        //Integer.MIN_VALUE Integer.MAX_VALUE
        if (num >= Integer.MIN_VALUE && num <= Integer.MAX_VALUE) {
            System.out.println("num在int类型的范围");
            //num在int类型的范围
        }
     }
}

构造方法

public Integer(int i)
public Integer(String s)
package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 12:13
 */
public class Test {
    public static void main(String[] args) {
        Integer integer = new Integer(123);
        Integer integer1 = new Integer("123");
        System.out.println(integer);
        //123
        System.out.println(integer1);
        //123

        Integer abc = new Integer("abc");
        //Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
        //数字格式异常,不能将非数字字符串转换为Integer类型
        System.out.println(abc);
    }
}

String类型和int类型的相互转换

String ---> int
	int i = new Integer(String s).intValue()
	int i = Integer.parseInt(String s)

int ---> String
	拼接空串:100 + ""
	String.valueOf(int i)
	new Integer(int i).toString() //调用对象的方法
package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 12:18
 */
public class Demo {
    public static void main(String[] args) {
        //String ---> int
        //方式一
        int i = new Integer("123").intValue();
        //intValue()相当于手动拆箱
        System.out.println(i);
        //方式二
        int i1 = Integer.parseInt("123");
        System.out.println(i1);


        //int ---> String
        //方式一
        String s = 100 + "";
        //方式二
        String s1 = String.valueOf(100);
        System.out.println(s1);
        //方式三
        Integer integer = new Integer(100);
        String s2 = integer.toString();
        System.out.println(s2);
    }
}

Integer的自动装箱、自动拆箱

自动拆装箱:JDK1.5之后引入的一个新特性。

  • 自动装箱:将一个基本数据类型自动转换为它所对应的包装类型
  • 自动拆箱:将一个包装类型自动转换成它所对应的基本数据类型
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/2 12:23
 */
public class MyTest {
    public static void main(String[] args) {
        Integer integer = 100;
        //自动装箱

        Integer integer1 = 200;
        //自动装箱
        int i = integer1;
        //自动拆箱
    }
}
Integer valueOf(int i)
//手动装箱

int intValue(Integer integer)
//手动拆箱
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/2 12:29
 */
public class MyDemo {
    public static void main(String[] args) {
        //手动装箱
        int num = 100;
        Integer integer = Integer.valueOf(num);

        //一步(自动装箱)
        Integer integer1 = 100;

        //手动拆箱
        Integer integer2 = 200;
        int i = integer2.intValue();
        
        //一步(自动拆箱)
        int j = integer2;
    }
}
Integer integer = 200;
integer += 100;
//首先自动拆箱,从Integer类型拆箱int类型,计算完毕后,从int类型自动装箱为Integer类型
package org.westos.demo2;

/**
 * @author lwj
 * @date 2020/5/2 12:36
 */
public class Test {
    public static void main(String[] args) {
        Integer[] arr = {10, 20, 30, Integer.valueOf(40), new Integer(50)};
        //自动装箱

        int sum = 0;
        for (Integer integer : arr) {
            sum += integer;
            //自动拆箱
        }
        System.out.println(sum);
        //150
    }
}

Integer的面试题

package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 11:04
 */
public class MyTest {
    public static void main(String[] args) {
        Integer integer = new Integer(127);
        Integer integer1 = new Integer(127);
        System.out.println(integer == integer1);
        //false
        //警告:包装类型间的相等判断应该用equals,而不是‘==‘
        System.out.println(integer.equals(integer1));
        //true

        Integer integer2 = new Integer(128);
        Integer integer3 = new Integer(128);
        System.out.println(integer2 == integer3);
        //false
        System.out.println(integer2.equals(integer3));
        //true

        Integer integer4 = 127;
        Integer integer5 = 127;
        System.out.println(integer4 == integer5);
        //true
        System.out.println(integer4.equals(integer5));
        //true

        Integer integer6 = 128;
        Integer integer7 = 128;
        System.out.println(integer6 == integer7);
        //false
        System.out.println(integer6.equals(integer7));
        //true
    }
}

Integer类内部有一个私有静态内部类IntegerCache。

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;
		//cache数组,length = (127+128) + 1 = 256
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
        //为cache数组的每个元素赋值,cache[0] = -128,cache[1] = -127,cache[255] = 128

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

所以使用

Integer i = 127;
Integer j = 127;

这种方式时,默认调用的是自动装箱方法,

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

所以,i和j指向同一个地址,用==比较时返回false。

[-128, 127]。

正则表达式

校验QQ号

package org.westos.demo;

import java.util.Scanner;

/**
 * @author lwj
 * @date 2020/5/2 13:49
 */
public class MyTest {
    public static void main(String[] args) {
        /*
        校验qq号
           1、5-15位数字
           2、0不能开头
         */
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的qq号:");
        String qq = sc.nextLine();
        boolean b = checkQqNumber2(qq);
        if (b) {
            System.out.println("规则正确");
        } else {
            System.out.println("规则不正确");
        }
    }

    /**
     * 采用正则表达式校验
     * @param qq
     * @return
     */
    private static boolean checkQqNumber2(String qq) {
        String regex = "[1-9][0-9]{4,14}";
        //0不能开头,其余4-14位必须是数字
        return qq.matches(regex);
    }

    /**
     * 利用以前的知识
     * @param qq
     * @return
     */
    public static boolean checkQqNumber(String qq) {
        int length = qq.length();
        if (length >= 5 && length <= 15 && !qq.startsWith("0")) {
            for (int i = 0; i < qq.length(); i++) {
                char c = qq.charAt(i);
                //Character.isDigit(char c) 返回c是否是数字字符
                if (!(Character.isDigit(c))) {
                    return false;
                }
            }
        } else {
            return false;
        }
        return true;
    }
}

校验手机号

package org.westos.demo;

import java.util.Scanner;

/**
 * @author lwj
 * @date 2020/5/2 14:07
 */
public class MyDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个手机号");
        String phone = sc.nextLine();
        boolean b = checkPhoneNumber2(phone);
        if (b) {
            System.out.println("手机号规则正确");
        } else {
            System.out.println("手机号规则错误");
        }
    }

    private static boolean checkPhoneNumber2(String phone) {
        String regex = "[1][^012][0-9]{9}";
        //手机号以1开头,第二位不能是012,其余9位必须是数字
        return phone.matches(regex);
    }

    public static boolean checkPhoneNumber(String phoneNumber) {
        //以1开头,并且是11位
        //第二位是3 4 5 6 7 8 9
        if (phoneNumber.startsWith("1") && phoneNumber.length() == 11) {
            char c = phoneNumber.charAt(1);
            if (c == ‘0‘ || c == ‘1‘ || c == ‘2‘) {
                return false;
            }
            for (int i = 2; i < phoneNumber.length(); i++) {
                char ch = phoneNumber.charAt(i);
                if (!(Character.isDigit(ch))) {
                    return false;
                }
            }
        } else {
            return false;
        }
        return true;
    }
}

正则表达式的规则

匹配单个字符

package org.westos.demo;


/**
 * @author lwj
 * @date 2020/5/2 14:32
 */
public class Test {
    public static void main(String[] args) {
        //定义正则表达式
        String regex = "a";
        //只能匹配单个字符a,相当于[a]
        boolean b = "aaa".matches(regex);
        System.out.println(b);
        //false



        regex = "[abc]";
        //匹配列表中的任意一个单个字符
        boolean matches = "a".matches(regex);
        System.out.println(matches);
        //true

        regex = "[abcdefgABCDEFG123456]";
        boolean matches1 = "1".matches(regex);
        System.out.println(matches1);
        //true
        boolean matches2 = "8".matches(regex);
        System.out.println(matches2);
        //false

        regex = "[a-z]";
        //匹配所有的小写字母
        boolean matches3 = "b".matches(regex);
        System.out.println(matches3);
        //true


        regex = "[a-zA-Z0-9]";
        boolean matches4 = "Q".matches(regex);
        System.out.println(matches4);
        //true

        //上面的所有正则表达式都是只能匹配一个单个字符,因为只有一个[]
    }
}
package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 15:10
 */
public class Demo {
    public static void main(String[] args) {
        String regex = "[^5-9]";
        //取反,不是5-9
        boolean matches = "1".matches(regex);
        System.out.println(matches);
        //true

        regex = "[^a-z]";
        //不是小写字母
        boolean matches1 = "A".matches(regex);
        System.out.println(matches1);
        //true

        regex = ".";
        //匹配单个任意字符
        boolean matches2 = "a".matches(regex);
        System.out.println(matches2);
        //true


        regex = "...";
        //匹配三个任意字符
        boolean matches3 = "abc".matches(regex);
        System.out.println(matches3);
        //true

        regex = "\.";
        //只匹配.本身
        boolean matches4 = ".".matches(regex);
        System.out.println(matches4);
        //true

        // | 或者 \|代表|(进行转义)

        regex = "\d";
        //匹配单个数字
        boolean matches5 = "0".matches(regex);
        System.out.println(matches5);
        //true


        regex = "\D";
        //匹配非数字 [^d]
        boolean matches8 = "a".matches(regex);
        System.out.println(matches8);
        //true

        regex = "\w";
        //匹配[a-zA-Z_0-9],包括下划线
        boolean matches6 = "b".matches(regex);
        System.out.println(matches6);
        boolean matches10 = "_".matches(regex);
        System.out.println(matches10);
        //true

        regex = "\W";
        //匹配非单词字符 [^w]
        boolean matches7 = "中".matches(regex);
        System.out.println(matches7);
        //true

        regex = "\s";
        //匹配空格
        boolean matches9 = " ".matches(regex);
        System.out.println(matches9);
        //true
    }
}

匹配多个字符

package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 15:51
 */
public class MyTest2 {
    public static void main(String[] args) {
        //匹配多个


        String regex = "[a-z]?";
        //?代表一次或一次也没有 [0, 1]
        boolean matches = "".matches(regex);
        System.out.println(matches);
        //true

        regex = "[a-z]*";
        //*代表零次或多次 [0, )
        boolean matches1 = "".matches(regex);
        System.out.println(matches1);
        //true

        regex = "[a-z]+";
        //+代表一次或多次 [1, )
        boolean matches2 = "abc".matches(regex);
        System.out.println(matches2);
        //true

        regex = "[a-z]{3}";
        //{3}代表恰好三次
        boolean matches3 = "bcd".matches(regex);
        System.out.println(matches3);
        //true

        regex = "[a-z]{4,}";
        //{4,}代表至少4次
        boolean matches4 = "afgjs".matches(regex);
        System.out.println(matches4);
        //true

        regex = "[0-9]{2,6}";
        //{2,6}代表至少2次不超过6次
        boolean matches5 = "12345".matches(regex);
        System.out.println(matches5);
        //true

        regex = "\w{6}";
        //[a-zA-Z_0-9]恰好6次
        boolean matches6 = "aA_123".matches(regex);
        System.out.println(matches6);
        //true
    }
}

验证网易邮箱格式

package org.westos.demo;

/**
 * @author lwj
 * @date 2020/5/2 16:12
 */
public class MyDemo2 {
    public static void main(String[] args) {
        //检验邮箱格式
        //6-18位字符,字母开头,字母、数字、下划线组成
        String regex = "[a-zA-Z]\w{5,17}@163\.com";
        boolean matches = "westos@163.com".matches(regex);
        System.out.println(matches);
        //true
    }
}

正则表达式的分割功能

String类的功能:public String[] split(String regex)
package org.westos.demo;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/2 16:35
 */
public class Test2 {
    public static void main(String[] args) {
        String regex = "[=]\w*";
        //*代表零个或多个[a-zA-Z_0-9]
        String name = "张三=asdas李四=asd12王五=asdas12刘六";
        String[] split = name.split(regex);
        System.out.println(Arrays.toString(split));
        //[张三, 李四, 王五, 刘六]
    }
}

正则表达式的替换功能

String类的功能:public String replaceAll(String regex,String replacement)
package org.westos.demo;

import java.util.NavigableMap;

/**
 * @author lwj
 * @date 2020/5/2 16:44
 */
public class Demo2 {
    public static void main(String[] args) {
        String regex = "特朗普|奥巴马";
        String str = "特朗普和奥巴马是美国总统。";
        String s = str.replaceAll(regex, "*");
        System.out.println(s);
        //*和*是美国总统。


        regex = "[特朗普奥巴马]";
        //任意一个字符
        String s2 = str.replaceAll(regex, "*");
        System.out.println(s2);
        //***和***是美国总统。


        String name = "张三=asdas李四=asd12王五=asdas12刘六";
        regex = "[=a-zA-Z_0-9]+";
        //+代表一个或多个[=a-zA-Z_0-9]
        String s1 = name.replaceAll(regex, "=");
        System.out.println(s1);
        //张三=李四=王五=刘六
    }
}

练习

package org.westos.demo1;

import java.util.Arrays;

/**
 * @author lwj
 * @date 2020/5/2 16:54
 */
public class MyTest {
    public static void main(String[] args) {
        //字符串:”91   27  46    38         50”,请写代码实现最终输出结果是:”27 38 46 50 91”
        String source = "91   27  46    38         50";
        String regex = "\s+";
        //匹配多个空格,至少一个
        String[] split = source.split(regex);
        int[] dest = new int[split.length];
        int index = 0;
        for (String str : split) {
            //Integer.parseInt(String s) 数字字符串转为int
            dest[index++] = Integer.parseInt(str);
        }
        //对int类型的数组进行排序
        Arrays.sort(dest);
        StringBuffer sb = new StringBuffer();
        //拼接数组元素
        for (int i = 0; i < dest.length; i++) {
            if (i == dest.length - 1) {
                sb.append(dest[i]);
            } else {
                sb.append(dest[i]).append(" ");
            }
        }
        String s = sb.toString();
        System.out.println(s);
        //27 38 46 50 91
    }
}

以上是关于15Java常用类(数组工具类Arrays)基本类型包装类(Integer类)正则表达式String的split(String regex)和replaceAll(String regex, (代码片的主要内容,如果未能解决你的问题,请参考以下文章

Java中的日历类/集合类/数学类/正则表达式/数组工具类等的常用方法与基本功能

10JAVA基础-常用类02

10JAVA基础-常用类02

java.util.Arrays操作数组的工具类的基本用法

Arrays工具类关于数组的两个常用方法

java常用的工具类