Java常用类库笔记

StringBuffer类

  • 在String类中有一条特性是String的内容一旦声明就不可改变,如果要改变,则改变String的引用地址,即重新开辟一个堆内存来存放新的内容并且指针指到指到这个内容。这时为方便快捷我们可以使用到StringBuffer类。
方法定义描述
public StringBuffer()StringBuffer的构造方法
public StringBuffer append(char c)/append(String str)/append(StringBuffer sb)在StringBuffer类中提供了大量的追加操作(与String中使用“+”类似),可以向StringBuffer类中追加内容,此方法可以添加任何类型的数据
public int indexOf(String str)查找指定字符串是否存在
public int indexOf(String str,int fromIndex)从指定位置开始查找指定字符串是否存在
public StringBuffer insert(int offset,String str)在指定位置处加上指字符串
public StringBuffer reverse()将内容反转保存
public StringBuffer replace(int start,int end,String str)指定内容替换
public int length()求出内容长度
public StringBuffer delete(int start,int end)删除内容长度
public String substring(int start)字符串截取,指定开始点
public String substring(int start,int end)截取指定范围的字符串
public String toString()Object类继承的方法,用于将内容变为String类型
  • 例:
public class test1 {
    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer();
        //1、字符串连接
        buffer.append("World").append("!!!");
        buffer.append("\n");
        buffer.append("数字 = ").append(1).append("\n");
        buffer.append("字符 = ").append('C').append("\n");
        buffer.append("布尔 = ").append(true);
        /**
         * World!!!
         * 数字 = 1
         * 字符 = C
         * 布尔 = true
         */
        //2、添加内容
        buffer.insert(0, "Hello ");
        /**
         * 0代表从长度的第几个开始,而不是下标。
         * Hello World!!!
         * 数字 = 1
         * 字符 = C
         * 布尔 = true
         * 张三 = 25岁
         */
        //3、字符串反转
        String str = buffer.reverse().toString();
        /**
         * 反转后为一个新的序列,需要声明该序列,即需要将其变为字符串
         * 岁52 = 三张
         * eurt = 尔布
         * C = 符字
         * 1 = 字数
         * !!!dlroW olleH
         */
        //4、替换指定范围内容
        buffer.reverse();
        buffer.replace(6, 11, "张三");
        /**
         * Hello 张三!!!
         * 数字 = 1
         * 字符 = C
         * 布尔 = true
         */
        //5、字符串截取
        String str1 = buffer.substring(6, 8);
        /**
         * 张三
         */
        //6、删除指定范围内的字符
        buffer.delete(6, 8);
        /**
         * Hello !!!
         * 数字 = 1
         * 字符 = C
         * 布尔 = true
         */
        //7、查找指定的内容是否存在
        if (buffer.indexOf("Hello") == -1) {
            System.out.println("没有找到指定内容。");
        } else {
            System.out.println("可以找到指定内容。");
        }
        /**
         * 可以找到指定内容。
         */
    }
}

Runtime类

  • Java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都会对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。
方法定义描述
public static Runtime getRuntime取得Runtime类的实例
public long freeMemory()返回Java虚拟机中的空闲内存余量
public void maxMemory()返回JVM最大内存余量
public void gc()运行垃圾回收器,释放空间
public Process exec(String command) throws IOException执行本机命令
  • 例子
public class Test2 {
    public static void main(String[] args) {
        //获取空间信息
        Runtime run = Runtime.getRuntime();
        System.out.println("JVM最大内存量:" + run.maxMemory());
        System.out.println("JVM空闲内存量:" + run.freeMemory());
        String str = "Hello " + "World" + "!!!";
        System.out.println(str);
        for (int i = 0; i < 1000; i++) {
            str += 'x';
        }
        System.out.println("操作之后的,JVM空闲内存量:" + run.freeMemory());
        run.gc();
        System.out.println("垃圾回收后,JVM空闲内存余量:" + run.maxMemory());
        /**
         * JVM最大内存量:3784310784
         * JVM空闲内存量:249986728
         * Hello World!!!
         * 操作之后的,JVM空闲内存量:245991592
         * 垃圾回收后,JVM空闲内存余量:3784310784
         */
    }
}

Runtime类与Process类

  • 除了观察内存使用量外,也可以直接使用Runtime类运行本机的可执行程序。
  • 用以下方法:
    Process可以进行系统进程的控制,如果要想通过程序让此进程消失,则可以直接使用Process类中的以下方法:
    public void destroy()
public class Test3 {
    public static void main(String[] args) {
        Runtime run = Runtime.getRuntime();
        Process pro = null;
        try {
            pro = run.exec("notepad.exe");//打开本机程序,必须进行异常处理。
        } catch (Exception e) {
            e.printStackTrace();//打印异常信息
        }
        try {
            Thread.sleep(5000);//让此线程存活5秒
        } catch (Exception e){
            e.printStackTrace();
        }
        pro.destroy();//结束此进程
    }
}

国际化程序

  • 国际化程序的实现要通过三个类实现Java程序的国际化操作。
    • java.util.Locale :用于表示一个国家的语言类。
    • java.util.ResourceBundle:用于访问资源文件。
    • java.text.MessageFormat:格式化资源文件的展位字符串。

Locale类

  • 构造方法:
方法定义描述
public Locale(String language)根据语言代码构造一个语言环境
public Locale(String language,String country)根据语言和国家构造一个语言环境

ResourceBundle类

方法描述
public static RescourceBundle getBundle(String baceName)取得RescurceBundle的实例,并指定要操作的资源文件名称
public static final RescoureBundle getBundle(String baceName,Local locale)取得ResoureBundle的实例,并指定要操作的资源文件名称和区域码
public final String getString(String key)根据key从资源中取出对应的value

System类

  • System类中的所有方法都是静态的。
方法定义描述
public static void exit(int status)系统退出,如果status为非0就表示退出
public static void gc()运行垃圾收集机制,调用的是Runtime类中的gc方法
public static long currentTimeMillis()返回以毫秒为单位的当前时间
public static void arraycopy (Object src,int srcPos,Object dest,int destPos,int length)数组复制操作
public static Properties getProperties()取得当前系统的全部属性
public static String getProperty(String key)根据键值取得属性的具体内容
  • 例子:
public class Test {
    public static void main(String[] args) {
        //计算一个程序执行的时间
        long startTime = System.currentTimeMillis();
        int sum = 0;
        for (int i = 0; i < 3000000; i++) {
            sum += i;
        }
        long endTime = System.currentTimeMillis();
        /**
         * 计算所花费时间为:2毫秒
         */
        System.out.println("计算所花费时间为:" + (endTime - startTime) + "毫秒");

        //取得本机的所有属性
        /**
         * @ description 文件默认编码:file.encoding = GBK;
         * @ description 文件分割符:file.separator = \;
         */
        System.getProperties().list(System.out);

        //列出指定属性
        System.out.println("系统版本为:" + System.getProperty("os.name")
                + System.getProperty("os.version")
                + System.getProperty("os.arch"));
        System.out.println("系统用户为:" + System.getProperty("user.name"));
        System.out.println("当前用户目录:" + System.getProperty("user.home"));
        System.out.println("当前用户工作目录:" + System.getProperty("user.dir"));
    }
}

垃圾对象的回收

  • Java中由垃圾的自动回收机制,可以不定期的释放Java中的垃圾空间,而且在前面讲解Runtime类时也已经了解了如何进行垃圾空间的释放。System类中也有一个gc()方法,该方法实际上是对Runtime类中的gc()方法的封装,功能与之类似。
  • 如果在对象回收之前要进行操作就要用到finalize()方法,如下:
protected void finalize() throws Throwable
  • 例子:
class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

	//这里finalize()方法的抛出是Throwable的异常。
    @Override
    public void finalize() throws Throwable {
        System.out.println("对象被释放-->" + this.toString());
    }
}

public class Test1 {
    public static void main(String[] args) {
        Person p = new Person("张三", 25);
        p = null;
        System.gc();
    }
}

对象的生命周期

  • 一个类加载后进行初始化,然后就可以进行对象的实例化,对象实例化时会调用构造方法来完成,当一个对象不再使用时就要等待被垃圾收集,然后对象终结,最终实现程序的卸载。

日期操作类

Date类

  • Date类是一个较为简单的类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个完善的日期,构造方法如下:
public Date()
  • 例子:
import java.util.Date;
//获取当前系统日期
public class DateTest {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println("当前日期为:" + date);
    }
}

Calendar类

  • Calendar类可以将取得的日期精确到毫秒,但这个类本身是一个抽象类,要使用抽象类必须依靠对象的多态性。
  • Calendar类中的常量:
常量描述
public static final int YEAR取得年
public static final int MONTH取得月
public static final int DAY_OF_MONTH取得日
public static final int HOUR_OF_DAY取得小时(二十四小时制)
public static final int MINUTE取得分
public static final int SECOND取得秒
public static final int MILLESECOND取得毫秒
  • Calendar类中的方法:
方法描述
public static Calendar getInstance()根据默认的时区实例化对象
public boolean after(Object when)判断一个日期是否在指定日期之后
public boolean before(Object when)判断一个日期是否在指定日期之前
public int get(int field)返回给定日历的值
  • 例子:
import java.util.Calendar;
import java.util.GregorianCalendar;
//获取系统当前的日期
public class CalendarTest {
    public static void main(String[] args) {
        Calendar calendar = new GregorianCalendar();
        System.out.println("年" + calendar.get(Calendar.YEAR));
        System.out.println("月" + (calendar.get(Calendar.MONTH) + 1));
        System.out.println("日" + calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println("时" + calendar.get(Calendar.HOUR_OF_DAY));
        System.out.println("分" + calendar.get(Calendar.MINUTE));
        System.out.println("秒" + calendar.get(Calendar.SECOND));
        System.out.println("毫秒" + calendar.get(Calendar.MILLISECOND));

    }
}

DateFormat类

  • 此类对日期进行格式化操作,将其变为符合中国人习惯的日期格式,DateFormat类的定义如下:
public abstract class DateFormat extends Format
  • 从定义上看DateFormat类是一个抽象类,所以肯定无法直接实例化,但是在此抽象类中提供了一个静态方法,可以直接取得本类的实例。

  • DateFormat类的常用方法:

方法描述
public static final DateFormat getDateInstance()得到默认的对象
public static final DateFormat getDateInstance(int style,Locale aLocale)根据Locale得到对象
public static final DateFormat getDateTimeInstance()得到日期时间对象
public static final DateFormat getDateTimeInstance(int dateStyle,int timeStyle,Locale aLocale)根据Locale得到日期时间对象
  • 例子:
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

public class DateFormatTest {
    public static void main(String[] args) {
        //获取当前日期和时间
        //DATE:2022-12-28
		//DATETIME:16:48:20
        DateFormat df1 = null;
        DateFormat df2 = null;
        df1 = DateFormat.getDateInstance();
        df2 = DateFormat.getTimeInstance();
        System.out.println("DATE:" + df1.format(new Date()));
        System.out.println("DATETIME:" + df2.format(new Date()));
        //获取当前日期和时间并用默认时间格式输出
        //DATE:2022年12月28日
		//DATETIME:下午04时48分20秒 CST
        DateFormat df3 = null;
        DateFormat df4 = null;
        df3 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD, new Locale("zh", "CN"));
        df4 = DateFormat.getTimeInstance(DateFormat.ERA_FIELD, new Locale("zh", "CN"));
        System.out.println("DATE:" + df3.format(new Date()));
        System.out.println("DATETIME:" + df4.format(new Date()));
    }
}

SimpleDateFormat类

  • 将日期时间转换为指定的模式,首先要定义出一个完整的日期转换模板,在模板中通过特定的日期标记可以将一个日期数字提取出来。
  • 日期格式化模板标记:
标记描述
y年,年份是4位数字,所以需要使用yyyy表示
M年中的月份,月份是两位数字,所以需要使用MM表示
d月中的天数,天数是两位数字,所以需要使用dd表示
H一天中的小时数(24小时),小时是两位数字,使用HH表示
m小时中的分钟数,分钟是两位数字,使用mm表示
s分钟中的秒数,秒是两位数字,使用ss表示
S毫秒数,毫秒是三位数字,使用SSS表示
  • SimpleDateFormat类中的常用方法:
方法描述
public SimpleDateFormat(String patter)通过一个指定的模板构造对象
public Date parse(String socurce)throws ParseException将一个包含日期的字符串变为Data类型
public final String format(Date date)将一个Date类型按照指定格式变为String类型
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//将日期转换为:2022 年 12 月 28 日 17 时 03 分 14 秒 255 毫秒
public class SimpleDateFormatTest {
    public static void main(String[] args) {
        String date = "2022-12-28 17:03:14:255";
        String pat1 = "yyyy-MM-dd HH:mm:ss:SSS";
        String pat2 = "yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 SSS 毫秒";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);
        Date d = null;
        try{
            d = sdf1.parse(date);
        } catch (ParseException e){
            e.printStackTrace();
        }
        System.out.println(sdf2.format(d));
    }
}

import java.text.SimpleDateFormat;
import java.util.Date;
//将日期转换为:Wed Dec 28 17:03:14 CST 2022
public class SimpleDateFormatTest {
    public static void main(String[] args) throws Exception {
        String date = "2022-12-28 17:03:14:255";
        String pat = "yyyy-MM-dd HH:mm:ss:SSS";
        SimpleDateFormat sdf = new SimpleDateFormat(pat);
        Date d = sdf.parse(date);
        System.out.println(d);
    }
}

  • 获取时间练习:
//实现一:

import java.util.Calendar;
import java.util.GregorianCalendar;

class DateTime {
    private Calendar calendar = null;

    public DateTime() {
        this.calendar = new GregorianCalendar();
    }

    public String getDate() {
        StringBuffer buf = new StringBuffer();
        buf.append(calendar.get(Calendar.YEAR)).append("-");
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append("-");
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append("-");
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append(":");
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append(":");
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append(".");
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        return buf.toString();
    }

    public String getDateComplete() {
        StringBuffer buf = new StringBuffer();
        buf.append(calendar.get(Calendar.YEAR)).append("年");
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append("月");
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append("日");
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append("时");
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append("分");
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append("秒");
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        buf.append("毫秒");
        return buf.toString();
    }

    public String addZero(int num, int len) {
        StringBuffer s = new StringBuffer();
        s.append(num);
        while (s.length() < len) {
            s.insert(0, "0");
        }
        return s.toString();
    }

    public String getTimeStamp() {
        StringBuffer buf = new StringBuffer();
        buf.append(calendar.get(Calendar.YEAR));
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        return buf.toString();
    }
}

/**
 * 系统日期:2022-12-28-18:03:55.347
 * 中文日期:2022年12月28日18时03分55秒347毫秒
 * 时间数:20221228180355347
 */

public class GetTime {
    public static void main(String[] args) {
        DateTime date = new DateTime();
        System.out.println("系统日期:" + date.getDate());
        System.out.println("中文日期:" + date.getDateComplete());
        System.out.println("时间数:" + date.getTimeStamp());
    }
}

//实现二:
import java.text.SimpleDateFormat;
import java.util.Date;

class DateTime1 {
    private SimpleDateFormat sdf = null;

    public String getDate() {
        this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        return this.sdf.format(new Date());
    }

    public String getDateComplete() {
        this.sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒SSS毫秒");
        return this.sdf.format(new Date());
    }

    public String getTimeStamp() {
        this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return this.sdf.format(new Date());
    }
}

//系统日期:2022-12-28-18:15:45.503
//中文日期:2022年12月28日18时15分45秒503毫秒
//时间数:20221228181545503
public class GetTime1 {
    public static void main(String[] args) {
        DateTime date = new DateTime();
        System.out.println("系统日期:" + date.getDate());
        System.out.println("中文日期:" + date.getDateComplete());
        System.out.println("时间数:" + date.getTimeStamp());
    }
}

Math类

  • Math类是数学操作类,提供了一系列的数学操作方法,包括求绝对值、三角函数等,在Math类中提供的一切方法都是静态方法,所以直接由类名称调用即可。
  • 一些常用方法:
public class MathTest {
    public static void main(String[] args) {
        System.out.println("求9的平方根:" + Math.sqrt(9.0));
        System.out.println("求两数的最大值(4和5):" + Math.max(4,5));
        System.out.println("求两数的最小值(4和5):" + Math.min(4,5));
        System.out.println("求2的3次方:" + Math.pow(2,3));
        System.out.println("四舍五入:" + Math.round(22.579));
    }
}

Random类

  • Random类随机数产生类,可以指定一个随机数的范围,然后产生在此范围中的数字。
  • Random类中的常用方法:
方法描述
public boolean nextBoolean()随机生成boolean值
public double nextDouble()随机生成一个double值
public float nextFloat()随机生成一个float值
public int nextInt()随机生成一个int值
public int nextInt(int n)随机生成给定最大值的int值
public long nextLong()随机生成long值
  • 例子:
import java.util.Random;
//生成10个不大于100的随机数
public class RandomTest {
    public static void main(String[] args) {
        Random rand = new Random();
        for (int i = 0; i < 10; i++) {
            System.out.println(rand.nextInt(100) + "\t");
        }
    }
}

NumberFormat类

  • NumberFormat类是数字的格式化类,即可以按照本地的风格习惯进行数字的显示。
  • 定义:
public abstract class NumberFormat extends Format
  • NumberFormat类的常用方法
方法描述
public static Locale[] getAvailableLocales()返回所有语言环境的数组
public static final NumberFormat getInstance()返回当前默认语言环境的数字格式
public static NumberFormat getInstance(Locale inLocale)返回指定语言环境的数字格式
public static final NumberFormat getCurrencyInstance()返回当前默认环境的货币格式
public static NumberFormat getCurrencyInstance(Locale inLocale)返回指定语言环境的数字格式
  • 例子:
//使用当前语言环境格式化数字
import java.text.NumberFormat;

public class NumberFormatTest {
    public static void main(String[] args) {
        NumberFormat nf = null;
        nf = NumberFormat.getInstance();
        System.out.println("格式化后的数字:" + nf.format(10000));
        System.out.println("格式化后的数字:" + nf.format(1000.345));
    }
}

DecimalFormat类

  • Decimal类的主要作用是格式化数字,要进行自定义格式化操作,则必须指定格式化操作的模板。
  • DecimalFormat格式化模板
标记位置描述
0数字代表阿拉伯数字,每一个0代表一个阿拉伯数字,如果该位不存在则显示0
#数字代表阿拉伯数字,每一个#表示一位阿拉伯数字,如果该位不存在则不显示
.数字小数点分隔符或货币的小数分隔符
-数字代表符号
,数字分组分隔符
E数字分隔科学计数法中的尾数和指数
;子模式边界分隔正数个负数子模式
%前缀或后缀数字乘以100并显示为千分数
\u2030前缀或后缀乘以1000并显示为千分数
\u00A4前缀或后缀货币记号,由货币替换。如果两个同时出现,则用国际货币符号替换;如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符。
,前缀或后缀用于在前缀或后缀中为特殊字符加引号,例如“#‘#”将123格式化为“#123”。要创建单引号本身,则连续使用两个单引号,例如“#o“clock”
  • 例子:
import java.text.DecimalFormat;

class FormatDemo {
    public void format(String pattern, double value) {
        DecimalFormat df = new DecimalFormat(pattern);
        String str = df.format(value);
        System.out.println("使用" + pattern + "格式化数字" + value + ":" + str);
    }
}

public class DecimalFormatTest {
    public static void main(String[] args) {
        FormatDemo demo = new FormatDemo();
        demo.format("###,###,###",111222.34567);
        demo.format("000,000,000",111222.34567);
        demo.format("####,###,###¥",111222.34567);
        demo.format("000,000,000¥",111222.34567);
        demo.format("##.###%",0.345678);
        demo.format("00.###%",0.345678);
        demo.format("###.###\u2030",0.345678);
    }
}

//使用###,###,###格式化数字111222.34567:111,222
//使用000,000,000格式化数字111222.34567:000,111,222
//使用####,###,###¥格式化数字111222.34567:111,222¥
//使用000,000,000¥格式化数字111222.34567:000,111,222¥
//使用##.###%格式化数字0.345678:34.568%
//使用00.###%格式化数字0.345678:34.568%
//使用###.###‰格式化数字0.345678:345.678‰

BigInteger类

  • 当一个数字非常大,则无法使用基本类型接收,以前可能会使用String类进行接收,现在我们可以使用BigInteger类进行操作。
  • BigInteger类的常用方法:
方法描述
public BigInteger(String val)将一个字符串变为BigInteger类型的数据
public BigInteger add(BigInteger val)加法
public BigInteger subtract(BigInteger val)减法
public BigInteger multipy(BigInteger val)乘法
public BigInteger divide(BigInteger val)除法
public BigInteger max(BigInteger val)返回两个大数字中的最大值
public BigInteger min(BigInteger val)返回两大数字中的最小值
public BigInteger[] divideAndRemainder(BigInteger val)除法操作,数组的第1个元素为除法的商,第二个元素为除法的余数
  • 例子:
import java.math.BigInteger;

public class BigIntegerTest {
    public static void main(String[] args) {
        BigInteger b1 = new BigInteger("123456789");
        BigInteger b2 = new BigInteger("987654321");
        System.out.println("加法操作:" + b2.add(b1));
        System.out.println("减法操作:" + b2.subtract(b1));
        System.out.println("乘法操作:" + b2.multiply(b1));
        System.out.println("除法操作:" + b2.divide(b1));
        System.out.println("最大值:" + b2.max(b1));
        System.out.println("最小值:" + b2.min(b1));
        BigInteger result[] = b2.divideAndRemainder(b1);
        System.out.println("商是:" + result[0] + "\n余数是:" + result[1]);
    }
}

//加法操作:1111111110
//减法操作:864197532
//乘法操作:121932631112635269
//除法操作:8
//最大值:987654321
//最小值:123456789
//商是:8
//余数是:9

BigDecimal类

  • 对于不需要准确计算精度的数字可以直接使用float或double,如果要精确计算,就必须使用BigDecimal类。
  • BigDecimal类的常用方法:
方法描述
public BigDecimal(double val)将double表示形式转换为BigDecimal
public BigDecimal(int val)将int表示形式转换为BigDecimal
public BigDecimal(String val)将字符串表示形式转换为BigDecimal
public BigDecimal add(BigDecimal augend)加法
public BigDecimal subtract(BigDecimal subtrahend)减法
public BigDecimal multiply(BigDecimal multiplicand)乘法
public BigDecimal divide(BigDecimal divisor)除法
  • 例子:
//进行四舍五入的四则运算
import java.math.BigDecimal;

class MyMath {

    //进行加法运算
    public static double add(double d1, double d2) {
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.add(b2).doubleValue();
    }

    //进行减法运算
    public static double sub(double d1, double d2) {
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.subtract(b2).doubleValue();
    }

    //进行乘法运算
    public static double mul(double d1, double d2) {
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.multiply(b2).doubleValue();
    }

    //进行除法运算
    public static double div(double d1, double d2, int len) {
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    //进行四舍五入操作
    public static double round(double d, int len) {
        BigDecimal b1 = new BigDecimal(d);
        BigDecimal b2 = new BigDecimal(1);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

public class BigDecimalTest {
    public static void main(String[] args) {
        System.out.println("加法运算:" + MyMath.round(MyMath.add(10.248, 9.999), 1));
        System.out.println("乘法运算:" + MyMath.round(MyMath.mul(10.248, 9.999), 3));
        System.out.println("除法运算:" + MyMath.div(10.248, 9.999, 3));
        System.out.println("减法运算:" + MyMath.round(MyMath.sub(10.248, 9.999), 3));
    }
}

//加法运算:20.2
//乘法运算:102.47
//除法运算:1.025
//减法运算:0.249

对象克隆技术

  • 在Java中支持对象的克隆操作,直接使用Object类中的clone()方法即可:
protected Object clone() throws CloneNotSupportedException
  • 以上方法是受保护类型,所以必须在子类中覆写此方法,而且覆写后应扩大访问权限,在对象所在的类中必须实现Cloneable接口才可以完成对象的克隆操作。Cloneable接口并没有任何方法定义,只是一种标识接口。
  • 例子:
class Person implements Cloneable {
    private String name = null;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException{
        //返回父类克隆之后的对象
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class CloneTest {
    public static void main(String[] args) throws Exception{
        Person p1 = new Person("张三");
        Person p2 = (Person) p1.clone();
        p2.setName("李四");
        System.out.println("原始对象:" + p1);
        System.out.println("克隆之后的对象:" + p2);
    }
}

Arrays类

  • 实现数组元素的查找、数组内容的填充、排序等。
  • Arrays类常用方法:
方法描述
public static boolean equals(int[] a,int[] a2)判断两个数组是否相等,此方法被重载多次,可以判断各种数据类型的数组。
public static void fill(int[] a,int val)将指定内容填充到数组之中,此方法被重载多次,可以填充各种类型的数据。
public static void sort(int[] a)数组排序,此方法被重载多次,可以对各种类型的数组进行排序。
public static int binarySearch(int[] a,int key)对排序后的数组进行检索,此方法被重载多次,可以对各种类型的数组进行搜索。
public static String toString(int[] a)输出数组信息,此方法被重载多次,可以输出各种数据类型的数组。
  • 例子
import java.util.Arrays;

public class ArraysTest {
    public static void main(String[] args) {
        int temp[] = {1, 3, 5, 7, 9, 2, 4, 6, 8};
        Arrays.sort(temp);
        System.out.println("排序后的数组:");
        System.out.println(Arrays.toString(temp));
        int point = Arrays.binarySearch(temp, 3);
        System.out.println("元素’3‘的位置在:" + point);
        Arrays.fill(temp, 3);
        System.out.println("数组填充:");
        System.out.println(Arrays.toString(temp));
        //排序后的数组:
        //[1, 2, 3, 4, 5, 6, 7, 8, 9]
        //元素’3‘的位置在:2
        //数组填充:
        //[3, 3, 3, 3, 3, 3, 3, 3, 3]
    }
}

Comparable接口

  • 比较器,对Object类的数组进行排序,要使用此方法也是有要求的,即对象所在的类必须实现Comparable接口。
public interface Comparable<T>{
	public int compareTo(T o);
}
  • Comparable接口也定义了Java泛型,只有一个compareTo()方法,返回值的int只能是:

    • 1:表示大于。
    • -1:表示小于。
    • 0:表示相等。
  • 例子:

import java.util.Arrays;

class Student implements Comparable<Student> {
    private String name;
    private int age;
    private float score;

    public Student(String name, int age, float score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override
    public int compareTo(Student s) {
        if (this.score > s.score) {
            return -1;
        } else if (this.score < s.score) {
            return 1;
        } else {
            if (this.age > s.age) {
                return 1;
            } else if (this.age < s.age) {
                return -1;
            } else {
                return 0;
            }
        }
    }
}

public class ComparableTest {
    public static void main(String[] args) {
        Student student[] = {new Student("张三", 25, 90.0f),
                new Student("李四", 23, 88.0f),
                new Student("王五", 26, 99.5f),
                new Student("沈六", 22, 100.0f),
                new Student("孙七", 30, 100.0f)
        };
        Arrays.sort(student);
        for (int i = 0; i < student.length; i++) {
            System.out.println(student[i]);
        }
    }
}
//Student{name='沈六', age=22, score=100.0}
//Student{name='孙七', age=30, score=100.0}
//Student{name='王五', age=26, score=99.5}
//Student{name='张三', age=25, score=90.0}
//Student{name='李四', age=23, score=88.0}

比较器原理

  • 二叉树排序法
class BinaryTree {
    class Node {
        private Comparable data;
        private Node left;
        private Node right;

        public void addNode(Node newNode) {
            if (newNode.data.compareTo(this.data) < 0) {
                if (this.left == null) {
                    this.left = newNode;
                } else {
                    this.left.addNode(newNode);
                }
            }
            if (newNode.data.compareTo(this.data) >= 0) {
                if (this.right == null) {
                    this.right = newNode;
                } else {
                    this.right.addNode(newNode);
                }
            }
        }

        public void printNode() {
            if (this.left != null) {
                this.left.printNode();
            }
            System.out.print(this.data + "\t");
            if (this.right != null) {
                this.right.printNode();
            }
        }
    }

    private Node root;

    public void add(Comparable data) {
        Node newNode = new Node();
        newNode.data = data;
        if (root == null) {
            root = newNode;
        } else {
            root.addNode(newNode);
        }
    }

    public void print() {
        this.root.printNode();
    }
}

public class BinaryTreeTest {
    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.add(8);
        bt.add(3);
        bt.add(3);
        bt.add(10);
        bt.add(9);
        bt.add(1);
        bt.add(5);
        bt.add(5);
        System.out.println("排序之后的结果:");
        bt.print();
    }
}
//排序之后的结果:
//1	3	3	5	5	8	9	10	
  • Integer为Comparable接口实例化
public class IntegerToComparable {
    public static void main(String[] args) {
        Comparable compar = null;
        compar = 30;
        System.out.println("内容为:" + compar);
    }
}
//内容为:30

另一种比较器Comparator

public interface Comparator<T>{
	public int compare(To1,To2);
	Boolean equals(Object obj);
}
  • 该类也存在一个compareTo方法,此方法要接收两个对象,其返回值依然是0,1,-1,但此接口需要单独指定好一个比较器的比较规则类才可以完成数组排序。

  • 例子:

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

class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Student)) {
            return false;
        }
        Student student = (Student) o;
        if (student.name.equals(this.name) && student.age == this.age) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String
    toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        if (s1.equals(s2)) {
            return 0;
        } else if (s1.getAge() < s2.getAge()) {
            return 1;
        } else {
            return -1;
        }
    }
}

public class ComparatorTest {
    public static void main(String[] args) {
        Student student[] = {new Student("张三", 20),
                new Student("李四", 22),
                new Student("王五", 20),
                new Student("沈六", 20),
                new Student("孙七", 22)
        };
        Arrays.sort(student,new StudentComparator());
        for (int i = 0; i < student.length; i++) {
            System.out.println(student[i]);
        }
    }
}
//Student{name='孙七', age=22}
//Student{name='李四', age=22}
//Student{name='沈六', age=20}
//Student{name='王五', age=20}
//Student{name='张三', age=20}

观察者设计模式

  • java.util包种提供了Observable类和Observer接口,使用它们即可完成观察者模式。
  • Observable类的常用方法:
方法描述
public void addObserver(Obsever o)添加一个观察者。
public void deleteObserver(Observer o)删除一个观察者。
protected void setChanged()被观察者状态发生改变。
public void notifyObservers(Object arg)通知所有观察者状态改变
  • 每一个观察者类都需要实现Observer接口,接口定义如下:
public interface Observer{
	void update(Observer o,Object arg);
}
  • 观察者模式的实现:
import java.util.Observable;
import java.util.Observer;

class House extends Observable {
    private float price;

    public House(float price) {
        this.price = price;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        super.setChanged();
        super.notifyObservers(price);
        this.price = price;
    }

    @Override
    public String toString() {
        return "房子的价格是:" + this.price;
    }
}

class HousePriceObserver implements Observer {
    private String name;

    public HousePriceObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        if (arg instanceof Float) {
            System.out.print(this.name + "观察到的价格更改为:");
            System.out.println(((Float) arg).floatValue());
        }
    }
}

public class ObserverTest {
    public static void main(String[] args) {
        House h = new House(1000000);
        HousePriceObserver hpo1 = new HousePriceObserver("购房者A");
        HousePriceObserver hpo2 = new HousePriceObserver("购房者B");
        HousePriceObserver hpo3 = new HousePriceObserver("购房者C");
        h.addObserver(hpo1);
        h.addObserver(hpo2);
        h.addObserver(hpo3);
        System.out.println(h);
        h.setPrice(666666);
        System.out.println(h);
    }
}
//房子的价格是:1000000.0
//购房者C观察到的价格更改为:666666.0
//购房者B观察到的价格更改为:666666.0
//购房者A观察到的价格更改为:666666.0
//房子的价格是:666666.0

正则表达式

  • 使用正则表达式可以方便地对数据进行匹配,还可以执行更加复杂的字符串验证、拆分、替换功能。
  • 使用正则表达式验证一串字符串由数字组成:
import java.util.regex.Pattern;

public class RegexTest {
    public static void main(String[] args) {
        String str = "123456789";
        if (Pattern.compile("[0-9]+").matcher(str).matches()) {
            System.out.println("是由数字组成。");
        } else {
            System.out.println("不是由数字组成。");
        }
    }
}
//是由数字组成。

Patter类和Matcher类、

  • 常用正规范
规范描述
\表示反斜线
\t表示制表符
\n表示换行
[abc]字符a、b或c
[^abc]表示除了a、b、c之外的字符
[a-zA-Z0-9]表示由字母、数字组成
\d表示数字
\D表示非数字
\w表示字母、数字、下划线
\W表示非字母、数字、下划线
\s表示所有空白字符
\S表示所有非空白字符
^行的开头
$行的结尾
.匹配除换行符之外的任意字符
  • 数量表示(X表示一组规范)
规范描述
X必须出现一次
X?可以出现0次或1次
X*可以出现0次、1次或多次
X+可以出现1次或多次
X{n}必须出现n次
X{n,}必须出现n次以上
X{n,m}必须出现n~m次
  • 逻辑运算符(X、Y表示一组规范)
规范描述
XYX规范后跟着Y规范
X\Y
(X)作为一个捕获组规范
  • Pattern类的常用方法
方法描述
public static Pattern compile(String regex)指定正则表达式规则
public Matcher matcher(CharSequence input)返回Matcher类实例
public String[] split(CharSequence input)字符串拆分
  • Matcher类的常用方法
方法描述
public boolean matches()执行验证
public String replaceAll(String replacement)字符串替换
  • 日期格式要求:yyyy-mm-dd
    • 正则表达式如下:
      日期:2022-1-5
      正则:\d{4}-\d{2}-\d{2}
  • 验证一个日期是否合法:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RiQiHeFa {
    public static void main(String[] args) {
        String str = "2022-01-05";
        String pat = "\\d{4}-\\d{2}-\\d{2}";
        Pattern p = Pattern.compile(pat);
        Matcher m = p.matcher(str);
        if (m.matches()) {
            System.out.println("日期格式合法。");
        } else {
            System.out.println("日期格式不合法。");
        }
    }
}
//日期格式合法。
  • 按照字符串的数字将字符拆分:
import java.util.regex.Pattern;

public class CharSplit {
    public static void main(String[] args) {
        String str = "A1C4597B65786E2D";
        String pat = "\\d+";
        Pattern p = Pattern.compile(pat);
        String s[] = p.split(str);
        for (int i = 0; i < s.length; i++) {
            System.out.print(s[i] + "\t");
        }
    }
}
//	A	C	B	E	D
  • 替换操作
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChangeTest {
    public static void main(String[] args) {
        String str = "A1C4597B65786E2D";
        String pat = "\\d+";
        Pattern p = Pattern.compile(pat);
        Matcher m = p.matcher(str);
        //用_替换数字。
        String newString = m.replaceAll("_");
        System.out.println(newString);
    }
}
//A_C_B_E_D

String类对正则表达式的支持

  • String类的正则支持
方法描述
public boolean matcher(String regex)字符串匹配
public String replaceAll(String regex,String replacement)字符串替换
public String[] split(String regex)字符串拆分
  • 用String类实现正则例子:
public class StringChange {
    public static void main(String[] args) {
        String str = "A1C4597B65786E2D".replaceAll("\\d+", "_");
        boolean temp = "2022-01-05".matches("\\d{4}-\\d{2}-\\d{2}");
        String s[] = "A1C4597B65786E2D".split("\\d+");
        System.out.println("字符串替换操作:" + str);
        System.out.println("字符串替换验证:" + temp);
        System.out.print("字符串拆分:");
        for (int i = 0; i < s.length; i++) {
            System.out.print(s[i] + "\t");
        }
    }
}

//字符串替换操作:A_C_B_E_D
//字符串替换验证:true
//字符串拆分:A	C	B	E	D	

定时调度

Timer类

  • Timer类是一种线程设施,可以用来实现在某一个时间或某一段时间后安排一个任务执行一次或定期重复执行。该功能要配合TimerTask配合使用。
  • Timer类种的常用方法:
方法描述
public Timer()用来创建一个定时器并启动该定时器。
public void cancel()用来终止该计时器,并放弃所有自己安排的任务,对当前正在执行的任务没有影响。
public int purge()将所有已经取消的任务移除,一般用来释放内存空间
public void schedule(TimerTask task,Data time)安排一个任务在指定时间执行,如果已超过该时间,则立即执行。
public void schedule(TimerTask task,Date firstTime,long period)安排一个任务在指定时间执行,然后以固定的频率(单位:毫秒)重复执行。
public void schedule(TimerTask task,long delay)安排一个任务在一段时间(毫秒)后执行。
public void schedule(TimerTask task,long delay,long period)安排一个任务在一段时间(毫秒)后执行,然后以固定频率(毫秒)重复执行。
public void scheduleAtFixedRate(TimerTask task,Date firstTime,long period)安排一个任务在指定时间执行,然后以近似固定的频率(毫秒)重复执行。
public void scheduleAtFixedRate(TimerTask task,long delay,long period)安排一个任务在一段时间(毫秒)后执行,然后以近似固定的频率(毫秒)重复执行。

TimerTask类

  • 要执行具体的任务,则必须使用TimerTask类,该类是抽象类,要使用该类,要自己建立一个类来继承此类,并实现其中的抽象方法。
  • TimerTask类中的常用方法:
方法描述
public void cancel()用来终止任务,如果该任务只执行一次且还没有执行,则永远不会再执行,如果为重复执行任务,则之后不会再执行(如果任务正在执行,则执行完后不会再执行)。
public void run()该任务所要执行的具体操作,该方法为引入的接口Runnable中的方法,子类需要覆写此方法。
public long scheduled ExecutionTime()返回最近一次要执行该任务的时间(如果正在执行,则返回此任务的执行安排时间),一般在run()方法中调用,用来判断当前是否有足够的时间来执行完成该任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值