Java基础类库

StringBuffer类

String类的特征

  • 每一个字符串的常量都属于一个String类的匿名对象, 并且不可更改
  • String有两个常量池: 静态常量池, 运行时常量池
  • String类对象实例化建议直接赋值的形式完成, 这样可以直接将对象保存在对象池之中以方便下次重用
  • String最大的弊端: 内容不允许修改, StringBuffer允许修改
String与StringBuffer的对比

StringBuffer并不像String类那样拥有两种对象实例化方式, StringBuffer必须像普通类对象那样首先进行对象实例化而后可以调用方法执行处理
构造方法

public StringBuffer();

数据追加

public StringBuffer append(数据类型 变量)   //   相当于字符串中的 "+" 操作

所有的 "+" 在编译以后都变成了StrngBuffer中的append()方法, 并且在程序之中StringBuffer和String可以相互转换:

  • String类对象变为StringBuffer可以依靠StringBuffer类的构造方法或者用append()方法
  • 所有的类对象都可以通过toString()转成String类对象
StringBuffer常用方法

1.插入数据

public StringBuffer insert(int offset, 数据类型 b)
public static void main(String[] args) {
        StringBuffer buf = new StringBuffer();
        buf.append("哈哈哈哈").insert(0, "yyyy").insert(4, "xxx");
        System.out.println(buf);
    }

2.删除数据

public StringBuffer delete(int start, int end)
public static void main(String[] args) {
        StringBuffer buf = new StringBuffer();
        buf.append("哈哈哈哈").insert(0, "yyyy").insert(4, "xxx").delete(2, 6);
        System.out.println(buf);
    }

3.字符串翻转

public StringBuffer reverse()
public static void main(String[] args) {
        StringBuffer buf = new StringBuffer();
        buf.append("哈哈哈哈").append("yyyy").reverse();
        System.out.println(buf);
    }

实际上与StringBuffer类还有一个类似的功能类StringBuilder类.StringBuffer是线程安全类, 方法全部使用了synchronized关键字修饰, 而StringBuilder类不是.

String, StringBufferStringBuilder三者的区别
  • String类是字符串的首选类型, 其最大的特点是内容不允许改变
  • StringBufferStringBuilder允许修改
  • StringBuffer是在JDK 1.0的时候提供的, 属于线程安全的操作, 而StringBuilder是在JDK1.5提供的不属于线程安全的操作

CharSequence

CharSequence是一个描述字符串结构的接口, 在这个接口里一般有三种常用的子类

String类 StringBuffer类 StringBuilder类
public final class String extends Object implemens Serializable, Comparable, CharSequence public final class StringBuffer extends Object implemens Serializable, CharSequence public final class StringBuilder extends Object implemens Serializable, CharSequence

CharSequence

现在只要有字符串就可以为CharSequence接口实例化.
CharSequence本身就是一个接口, 在该接口之中也定义了如下的操作方法

  • 获取指定索引字符: public char charAt(int index);
  • 获取字符串的长度: public int length();
  • 截取部分字符串: public CharSequence subSequence(int start, int end)

AutoCloseable

主要用于实现资源的自动关闭(释放资源)

  • 关闭方法: public void close() throws Exception;
    AutoCloseable

    注意事项
  • 要想实现自动关闭处理, 除了要使用AutoCloseable之外, 还需要结合有异常处理语句才可以正常调用

Runtime类

Runtime描述的事运行时的状态, 也就是在整个JVM中, Runtime类是唯一一个与JVM运行状态有关的类, 并且会默认提供一个该类的实例化对象.
由于在一个JVM进程只允许有一个Runtime类的对象, 所以类的构造方法被私有化, Runtime类使用的是单例设计模式
由于是单例设计模式, 如果想获取实例化对象, 那么就要依靠类中的getRuntime()方法完成.

  • 获取实例化对象: public static Runtime getRuntime();
  • 获取最大可用内存空间: public long maxMemory() // 默认配置为本机系统内存的1/4
  • 获取可用内存空间: public long totalMemory() // 默认配置是本机系统的1/64
  • 获取空闲内存空间: public long freeMemory()
  • 手工进行GC处理: public void gc()
Runtime

System类

  • 数组拷贝: public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
  • 获取当前的日期时间数值: public static long currentTimeMillis();
  • 进行垃圾回收: public static void gc();
利用currentTimeMillis获取操作耗时
public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 30000; i++) {
            System.out.println("i");
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);

    }
System也提供了一个gc方法, 这个方法并不是重新定义的新方法, 而是继续执行了Runtime类中的gc方法.

对象克隆

所谓的对象克隆, 其实就是深复制, 用已有对象的内容创建一个新的对象. 需要使用到Object类中提供的clone方法:

protected Object clone() throws CloneNotSupportedException;

所有的类都会继承Object父类, 所以所有的类都一定有clone()方法, 如果想实现对象克隆, 那么对象所在的类需要实现一个Cloneable接口

class Eg implements Cloneable {
    private int age;
    private String name;
    public Eg(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "[" + super.toString() + "]" + ", age:" + this.age + ", name:" + this.name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Main {
    public static void main(String[] args) throws Exception {
        Eg eg = new Eg("A", 20);
        Eg egs = (Eg)eg.clone();
        System.out.println(eg);
        System.out.println(egs);
    }
}

Math数学计算类

Math构造方法被私有化, 但是并不是单例, 所有的方法均是static.都可以通过类名直接调用.

Random随机数生成类

  • 产生一个不大于边界的随机数(正整数和0): public int nextInt(int bound)

大数字处理类

大数字处理类可以实现海量数字的计算(能提供的也只是基础计算),
大数字处理类分为两种:

  • BigInteger
    BigInteger类构造: public BigInteger(String val);
  • BigDecimal
    BigDecimal类构造: public BigDecimal(String val);

两个类均继承Number

Number类

四则运算

public static void main(String[] args) throws Exception {
        BigInteger bigA = new BigInteger("273827382738927837");
        BigInteger bigB = new BigInteger("273827382738927837");
        System.out.println(bigA.add(bigB)); // 加法
        System.out.println(bigA.subtract(bigB)); // 减法
        System.out.println(bigA.multiply(bigB)); // 乘法
        System.out.println(bigA.divide(bigB)); // 除法
        BigInteger result [] = bigA.divideAndRemainder(bigB);
        System.out.println("商:" + result[0] + ", 余数:" + result[1]);
    }

Date日期处理类

Date类的构造方法

 public Date() {
        this(System.currentTimeMillis());
}
public Date(long date) {
        fastTime = date;
}

获取当前日期

public static void main(String[] args) throws Exception {
        Date date = new Date();
        System.out.println(date);
    }

获取当前时间戳

public static void main(String[] args) throws Exception {
        long currentTime = new Date().getTime();
        System.out.println(currentTime);
}

将时间戳转为日期

public static void main(String[] args) throws Exception {
        long time = 1563375702346L;
        Date date = new Date(time);
        System.out.println(date);
}

SimpleDateFormat

`SimpleDateFormat`的继承关系

构造方法: public SimpleDateFormat(String pattern);

格式化日期

  • 日期格式化: public final String format(Date date);
  • 将字符串转为日期: public Date parse(String source) throws ParseException;

日期格式

年(yyyy)-月(MM)-日(dd)  时(HH):分(mm):秒(ss).毫秒(SSS)

将当前时间格式化

public static void main(String[] args) throws Exception {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        System.out.println(format.format(date));
        
    }

将某个时间转为日期

String str = "2019-07-17 22:57:36.029";
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = fmt.parse(str);
        System.out.println(date);

将某个时间戳格式化

public static void main(String[] args) throws Exception {
        long time = 1563375702346L;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        System.out.println(format.format(time));
}

将某个日期转成时间戳

 public static void main(String[] args) throws Exception {
        String str = "2019-07-17 22:57:36.029";
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = fmt.parse(str);
        System.out.println(date.getTime());
}

NumberFormat(货币格式化)

public static void main(String[] args) throws Exception {
        double money = 2829839389d;
        String moneyStr = NumberFormat.getInstance().format(money);
        System.out.println(moneyStr);
    }

输出

2,829,839,389

UUID类

UUID 根据时间戳生成一个无重复的字符串定义.

  • 获取UUID对象: public static UUID randomUUID();
  • 根据字符串获取UUID对象: public static UUID fromString(String name);
public static void main(String[] args) throws Exception {
        UUID uuid = UUID.randomUUID();
        String uuidStr = uuid.toString();
        uuid = UUID.fromString(uuidStr);
        System.out.println(uuidStr);
        System.out.println(uuid);
}

Optional

可以实现null的处理操作, 提供了以下的操作方法:

  • 返回空数据: public static Optional empty();
  • 获取数据: public T get();
  • 保存数据, 但是不允许出现null: public static Optional of(T value);
    • 如果在保存数据的时候存在null, 则会抛出NullPointerException异常;
  • 保存数据, 允许为空: public static Optional ofNullable(T value);
  • 空的时候返回其他数据: public T orElse(T other)

ThreadLocal

ThreadLocal主要用于解决多线程资源引用传递的问题, 很多地方叫做线程本地变量,也有些地方叫做线程本地存储, 即按照线程来存储数据.

  • 构造方法
public ThreadLocal();
  • 设置数据
public void set(T value);
  • 取出数据
public T get();
  • 删除数据
public void remove();

问题代码
三个线程发送三个消息.

class Message { // 要发送的消息体
    private String info;
    public void setInfo(String info) {
        this.info = info;
    }
    public String getInfo() {
        return info;
    }
}
class Channel { // 消息的发送通道
    private static Message message;
    private Channel() {}
    public static void setMessage(Message m) {
        message = m;
    }
    public static void send() {
        System.out.println("[" + Thread.currentThread().getName() + ", 消息发送" + message.getInfo());
    }
}
public class JavaAPIDemo {
    public static void main(String[] args) {
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息A");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程A").start();
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息B");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程B").start();
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息C");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程C").start();
    }
}

输出结果(跑几次)

[线程A, 消息发送发送消息A
[线程B, 消息发送发送消息A
[线程C, 消息发送发送消息C

问题产生: 多个线程之间的消息产生了相互影响, 主要的原因是Channel中的message使用的是static定义的, 在B线程先给message赋值, 尚未发送的时候, A线程重新赋值, 然后A线程发出, B线程发出, 导致出现问题

在不改变代码结构的情况下需要使用ThreadLocal解决这个问题, 代码如下:

class Message { // 要发送的消息体
    private String info;
    public void setInfo(String info) {
        this.info = info;
    }
    public String getInfo() {
        return info;
    }
}
class Channel { // 消息的发送通道
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();
    private Channel() {}
    public static void setMessage(Message m) {
        THREAD_LOCAL.set(m); // 想ThreadLocal中保存数据
    }
    public static void send() {
        System.out.println("[" + Thread.currentThread().getName() + ", 消息发送:" + THREAD_LOCAL.get().getInfo());
    }
}
public class JavaAPIDemo {
    public static void main(String[] args) {
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息A");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程A").start();
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息B");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程B").start();
        new Thread(()->{
            Message msg = new Message();
            msg.setInfo("发送消息C");
            Channel.setMessage(msg);
            Channel.send();
        }, "线程C").start();
    }
}

输出结果, 不论运行多少次, 线程和消息都可以一一对应

[线程B, 消息发送:发送消息B
[线程A, 消息发送:发送消息A
[线程C, 消息发送:发送消息C
ThreadLocal

定时调度

定时器的主要操作就是定时任务的处理, 只是实现了一种间隔出发的操作.
如果想要实现定时的处理操作, 主要需要有一个定时操作的主体类, 以及定时任务的控制, 可以使用两个类来控制

  • java.util.TimerTask类: 实现定时任务处理
  • java.util.Timer类: 进行任务的启动
    • 任务启动: public void schedule(TimerTask task, long delay); //delay为延时, 延时的单位是毫秒
    • 间隔触发: public void scheduleAtFixedRate(TimerTask task, long delay, long period);
class myTask extends TimerTask {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + ": " + System.currentTimeMillis());
    }
}

public class JavaAPIDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        // 定义间隔任务, 1000毫秒后开始执行, 每次执行1次, 周期为1000毫秒
        timer.scheduleAtFixedRate(new myTask(), 1000, 1000);
    }
}

Base64

since: JDK1.8

  • Base64.Encoder: 进行加密处理
    • 加密处理: public byte[] encode(byte[] src);
  • Base64.Decoder: 进行解密处理
    • 解密处理: public byte[] decode(String src);
 public static void main(String[] args) {
        String msg = "这是需要加密的字符串";
        String encMsg = new String(Base64.getEncoder().encode(msg.getBytes()));
        System.out.println("encMsg:" + encMsg);
        String decMsg = new String(Base64.getDecoder().decode(encMsg.getBytes()));
        System.out.println("decMsg:" + decMsg);
  }

最好的加密应该增加盐值, 并且盐值先加密, 最后使用2-3种加密方式.

比较器

系统类型(Integer, String)数组比较, 一般使用sort(). 自定义对象比较, 一般使用比较器.

Comparable比较器

实现一个Person类, 比较年纪

class Person implements Comparable {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.age = age;
        this.name = name;
    }

    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }

    @Override
    public String toString() {
        return "姓名:" + this.name + ", 年龄:" + this.age;
    }
}
public class JavaAPIDemo {
    public static void main(String[] args) {
        Person perA = new Person("小强A", 26);
        Person perB = new Person("小强B", 126);
        Person perC = new Person("小强C", 86);
        Person list [] = new Person[] {
                perA,
                perB,
                perC
        };
        Arrays.sort(list);
        System.out.println(Arrays.toString(list));
    }
}
Comparator比较器

Comparator是一种挽救的比较器支持, 目的是解决一些没有使用Comparable排序的类的数组排序操作.
比如上面的Person类并没有继承Comparable, 在Person类本体不被修改的情况下, 需要进行排序

class PersonComparator implements Comparator {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}
class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return this.age;
    }
    public String getName() {
        return this.name;
    }
    @Override
    public String toString() {
        return "姓名:" + this.name + ", 年龄:" + this.age;
    }
}
public class JavaAPIDemo {
    public static void main(String[] args) {
        Person perA = new Person("小强A", 26);
        Person perB = new Person("小强B", 126);
        Person perC = new Person("小强C", 86);
        Person list [] = new Person[] {
                perA,
                perB,
                perC
        };
        Arrays.sort(list, new PersonComparator());
        System.out.println(Arrays.toString(list));
    }
}

排序尽量使用Comparable.

ComparableComparator的区别

  • java.lang.Comparable是在类定义的时候实现的父接口, 主要用于定义排序规则, 里面只有一个compareTo的方法
  • java.util.Comparator是挽救的比较器操作, 需要单独设置比较器规则类实现排序, 里面有compare方法.

你可能感兴趣的:(Java基础类库)