Java基础类库

2019-07-16  本文已影响0人  Roct

StringBuffer类

String类的特征

String与StringBuffer的对比

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

public StringBuffer();

数据追加

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

所有的 "+" 在编译以后都变成了StrngBuffer中的append()方法, 并且在程序之中StringBuffer和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三者的区别

CharSequence

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

String类 StringBuffer类 StringBuilder类
public final class String extends Object implemens Serializable, Comparable<String>, CharSequence public final class StringBuffer extends Object implemens Serializable, CharSequence public final class StringBuilder extends Object implemens Serializable, CharSequence
CharSequence
现在只要有字符串就可以为CharSequence接口实例化.
CharSequence本身就是一个接口, 在该接口之中也定义了如下的操作方法

AutoCloseable

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

Runtime类

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

Runtime

System类

利用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随机数生成类

大数字处理类

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

两个类均继承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);

格式化日期

日期格式

年(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 根据时间戳生成一个无重复的字符串定义.

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的处理操作, 提供了以下的操作方法:

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<Message> THREAD_LOCAL = new ThreadLocal<Message>();
    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

定时调度

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

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

 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<Person> {
    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<Person> {
    @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的区别

上一篇 下一篇

猜你喜欢

热点阅读