美文网首页
开发支持类库

开发支持类库

作者: 曾梦想仗剑天涯 | 来源:发表于2020-12-23 17:33 被阅读0次

    UUID类

    • UUID是一种生成无重复字符串的一种程序类,这种程序类的主要功能是根据时间戳实现一个自动的无重复的字符串定义;
    • 一般在获取UUID的时候往往都是随机生成一个内容,所以可以通过如下方式获取:
      • 获取UUID对象:public static UUID randomUUID()
      • 根据字符串获取UUID内容:public static UUID fromString(String name)
    import java.util.UUID;
    public class UUIDApi {
        public static void main(String[] args) {
            UUID uid = UUID.randomUUID();
            System.out.println(uid);
        }
    }
    
    • 在对一些文件进行自动命名处理的情况下,UUID类型非常好用;

    Optional类

    • Optional类的主要功能是进行null的相关处理,为了防止空指向异常,往往可以追加有null的验证;
    package com.company.OptionalApi;
    interface IMessage {
        public String getContent();
    }
    class MessageImpl implements IMessage {
        @Override
        public String getContent() {
            return "Hello World";
        }
    }
    class MessageUtil {
        private MessageUtil() {
        }
        public static IMessage getMessage() {
            return null;
        }
        public static void useMessage(IMessage msg) {
            if (msg != null) {
                System.out.println(msg.getContent());       //有可能会出现null而导致空指向
            }
        }
    }
    public class OptionalApi {
        public static void main(String[] args) throws Exception {
            MessageUtil.useMessage(MessageUtil.getMessage());
        }
    }
    
    • 在引用接收的一方往往都是被动的进行判断,所以为了解决这种被动的处理操作,在Java类中提供有一个Optional类,这个类可以实现null的处理操作,提供有如下的一些操作方法:
      • 返回空的数据:public static <T> Optional<T> empty()
      • 获取数据:public T get()
      • 保存数据,但是不允许出现null:public static <T> Optional<T> of(T value),如果保存时出现了null则会抛出NullPointerException的异常
      • 保存数据,允许为null:public static <T> Optional<T> ofNullable(T value)
      • 空的时候,返回其他数据:public T orElse(T other)
    此图来源于李兴华老师
    package com.company.OptionalApi;
    import java.util.Optional;
    interface IMessage {
        public String getContent();
    }
    class MessageImpl implements IMessage {
        @Override
        public String getContent() {
            return "Hello World";
        }
    }
    class MessageUtil {
        private MessageUtil() {
        }
        public static Optional<IMessage> getMessage() {
            return Optional.of(new MessageImpl());
        }
        public static void useMessage(IMessage msg) {
            if (msg != null) {
                System.out.println(msg.getContent());       //有可能会出现null而导致空指向
            }
        }
    }
    public class OptionalApi {
        public static void main(String[] args) throws Exception {
            IMessage msg = MessageUtil.getMessage().get();
            MessageUtil.useMessage(msg);
        }
    }
    
    • 如果现在数据保存的内容是null,则会在保存处出现异常;
    public static Optional<IMessage> getMessage() {
        return Optional.of(null);
    }
    
    • 由于Optional类中允许保存有null的内容,所以数据在获取的时候也可以进行null的处理,如果此时为null,在get()时就会抛出异常,此时可以更换为orElse()方法;
    public class OptionalApi {
        public static void main(String[] args) throws Exception {
            IMessage msg = MessageUtil.getMessage().orElse(new MessageImpl());
            MessageUtil.useMessage(msg);
        }
    }
    

    ThreadLocal类

    package com.company.ThreadLocal;
    class Channel {
        private static Message message;
        private Channel() {
        }
        public static void setMessage(Message m) {
            message = m;
        }
        public static void send() {
            System.out.println("【消息发送】" + message.getInfo());
        }
    }
    class Message {
        private String info;
        public void setInfo(String info) {
            this.info = info;
        }
        public String getInfo() {
            return info;
        }
    }
    public class ThreadLocalApi {
        public static void main(String[] args) throws Exception {
            Message msg = new Message();
            msg.setInfo("Hello World");
            Channel.setMessage(msg);
            Channel.send();
        }
    }
    
    • 上面所展示程序是以单线程的模式来进行处理的,那么如果在多线程的状态下能否实现完全一致的操作效果呢?为此我们启用三个线程进行处理;
    public class ThreadLocalApi {
        public static void main(String[] args) throws Exception {
            for (int x = 0; x < 3; x++) {
                int num = x;
                new Thread(() -> {
                    Message msg = new Message();
                    msg.setInfo("第" + num + "个消息");
                    Channel.setMessage(msg);
                    Channel.send();
                }, "线程" + num).start();
            }
        }
    }
    
    • 这个时候消息的处理产生了影响;
    此图来源于李兴华老师
    • 在保持Channel(所有消息发送的通道)核心结构不发生改变的情况下,需要考虑到每个线程的独立操作问题,这样的情况下就发现对于Channel类而言除了要保留有发送的消息之外,还应该多存放有一个每一个线程的标记(当前线程),那么这个时候就可以通过ThreadLocal类来存放数据;
    • 在ThreadLocal类里面提供有如下的操作方法:
      • 构造方法:public ThreadLocal()
      • 设置数据:public void set(T value)
      • 取出数据:public T get()
      • 删除数据:public void remove()
      • public class ThreadLocal<T> extends Object
    此图来源于李兴华老师
    package com.company.ThreadLocal;
    class Channel {
        private static final ThreadLocal<Message> THREADLOCAL = new ThreadLocal<Message>();
        private Channel() {}
        public static void setMessage(Message m) {
            THREADLOCAL.set(m);
        }
        public static void send() {
            System.out.println(Thread.currentThread().getName() + "、【消息发送】" + THREADLOCAL.get().getInfo());
        }
    }
    class Message {
        private String info;
        public void setInfo(String info) {
            this.info = info;
        }
        public String getInfo() {
            return info;
        }
    }
    public class ThreadLocalApi {
        public static void main(String[] args) throws Exception {
            for (int x = 0; x < 3; x++) {
                int num = x;
                new Thread(() -> {
                    Message msg = new Message();
                    msg.setInfo("第" + num + "个消息");
                    Channel.setMessage(msg);
                    Channel.send();
                }, "线程" + num).start();
            }
        }
    }
    
    • 每一个线程通过ThreadLocal只允许保存一个数据;

    定时器

    • 定时器的主要操作是进行定时任务的处理,在Java中提供有定时任务的支持,但是这种任务的处理只是实现了一种间隔触发的操作;
    • java.util.TimerTask类:实现定时任务处理;
    • java.util.Timer类:进行任务的启动,启动的方法:
      • 任务启动:public void schedule(TimerTask task, long delay),延迟单位为毫秒;
      • 间隔触发:public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
    package com.company.TimerApi;
    import java.util.Timer;
    import java.util.TimerTask;
    class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "、定时任务,当前时间:" + System.currentTimeMillis());
        }
    }
    public class TimerApi {
        public static void main(String[] args) throws Exception {
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(new MyTask(), 100, 1000);
            //timer.schedule(new MyTask(), 1000);
        }
    }
    

    Base64加密与解密

    • 正常来讲加密基本上永远都要伴随着解密,所谓的加密或者是解密往往都需要有一些规则,从JDK1.8开始提供有新的加密处理操作类,Base64处理,在这个类里面有两个内部类:
      • Base64.Encoder:进行加密处理,public byte[] encode(byte [] src)
      • Base64.Decoder:进行解密处理,public byte[] decode(byte [] src)
    package com.company.Base64APi;
    import java.util.Base64;
    public class Base64Api {
        public static void main(String[] args) throws Exception {
            String msg = "Hello World";
            String enMsg = new String(Base64.getEncoder().encode(msg.getBytes()));
            System.out.println(enMsg);
            String deMsg = new String(Base64.getDecoder().decode(enMsg));
            System.out.println(deMsg);
        }
    }
    
    • 虽然Base64可以实现加密和解密的处理,但是其由于是一个公版的算法,所以如果直接对数据进行加密往往并不安全,那么最好的做法是使用盐值操作:
    String salt = "Mars";
    String msg = "Hello World" + "{" + salt + "}";
    
    • 即便有盐值实际上发现加密效果也不好,最好的做法是多次加密;
    package com.company.Base64APi;
    import java.util.Base64;
    class StringUtil {
        private static final String SALT = "Mars";
        private static final int REPEAT = 5;
        /** 
        * @Description: 加密处理 
        * @Param: [str要加密的字符串需要与盐值整合]
        * @return: java.lang.String 加密后的数据
        * @Author: mars_wu
        * @Date: 2020/12/25 下午6:14
        */ 
        public static String encode(String str) {
            String temp = str + "{" + SALT + "}";
            byte [] data = temp.getBytes();
            for (int x = 0; x < REPEAT; x++) {
                data = Base64.getEncoder().encode(data);
            }
            return new String(data);
        }
        /** 
        * @Description: 解密处理 
        * @Param: [str要解密的内容]
        * @return: java.lang.String 解密后的原始数据
        * @Author: mars_wu
        * @Date: 2020/12/25 下午6:22
        */ 
        public static String decode(String str) {
            byte [] data = str.getBytes();
            for (int x = 0; x < REPEAT; x++) {
                data = Base64.getDecoder().decode(data);
            }
            return new String(data).replaceAll("\\{\\w+\\}", "");
        }
    }
    public class Base64Api {
        public static void main(String[] args) throws Exception {
            String str = StringUtil.encode("Hello World");
            System.out.println(StringUtil.decode(str));
        }
    }
    

    相关文章

      网友评论

          本文标题:开发支持类库

          本文链接:https://www.haomeiwen.com/subject/cwrunktx.html