UUID类
UUID是一种生成无重复字符串的一种程序类,这种程序类的主要功能是根据时间戳实现一个自动的无重复的字符串定义。
一般在获取UUID的时候往往都是随机生成一个内容,所以可以通过如下方式获取对象:
- 获取UUID对象:
public static UUDI randomUUID();
- 根据字符串获取UUID内容:
public static UUID fromString(String name);
import java.util.UUID;
public class JavaDemo {
public static void main(String[] args) throws Exception{
UUID uid = UUID.randomUUID() ;
System.out.println(uid.toString());
}
}
#6f2a592c-20c1-46a8-8125-f3fb122d3dd3
在对一些文件自动命名处理的情况下,UUID非常好用。
Optional类
Optional类主要功能是进行null的相关处理。在传统引用问题,引用接收的一方往往都是被动的进行判断。为了解决这种被动的处理操作,Java类中提供有一个Optional类,可以实现null的处理操作。如下操作方法:
- 返回空数据:
public static <T>Optional<T>empty();
- 获取数据:
public T get();
- 保存数据,但不是允许出现null:
public static<T>Optional<T>of(T value);
|- 如果在保存数据的时候存在null,则会抛出NullPointerException异常; - 保存数据,允许为空:
public static <T> Optional<T>ofNullable(T value);
- 空的时候返回其它数据:
public T orElse(T other)
;
package demo;
import java.util.Optional;
public class JavaDemo {
public static void main(String[] args) throws Exception{
IMessage temp = MessageUtil.getMessage().get();//获取数据
MessageUtil.useMessage(temp);
}
}
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());//有可能出现空导致空指向
}
}
}
interface IMessage{
public String getContent();
}
class MessageImpl implements IMessage{
@Override
public String getContent() {
return "be better!";
}
}
#be better!
如果现在保存的数据内容是null,则就会在保存处出现异常
public static Optional<IMessage> getMessage(){
return Optional.of(null);//有对象
}
由于Optional类中允许保存有null的内容,所以在数据获取的时候也可以进行null
的处理。但是如果为空,则在使用get()
的时候就会出现异常信息,所以此时可以更换为orElse()
方法 。
package demo;
import java.util.Optional;
import java.util.UUID;
public class JavaDemo {
public static void main(String[] args) throws Exception{
IMessage temp = MessageUtil.getMessage().orElse(new MessageImpl());//获取数据
MessageUtil.useMessage(temp);
}
}
class MessageUtil{
private MessageUtil() {}
public static Optional<IMessage> getMessage(){
return Optional.ofNullable(null);//有对象
}
public static void useMessage(IMessage msg) {
if (msg != null) {
System.out.println(msg.getContent());//有可能出现空导致空指向
}
}
}
interface IMessage{
public String getContent();
}
class MessageImpl implements IMessage{
@Override
public String getContent() {
return "be better!";
}
}
#be better!
在所有引用数据类型的操作处理之中,null是一个重要的技术问题,所以JDK1.8后提供的这个新的类对于null的处理很有帮助,同时也是日后今后开发项目之中使用次数很多的一个程序类。
ThreadLocal类
- 构造方法:
public ThreadLocal();
- 设置数据:
public void set(T value);
- 取出数据:
public T get();
- 删除数据:
public void remove()
;
【范例】解决线程同步问题
package demo;
public class JavaDemo {
public static void main(String[] args) throws Exception {
new Thread(() -> {
Message msg = new Message();// 实例化消息主体对象
msg.setInfo("第一个线程消息");// 设置要发送的内容
Channel.setMessage(msg);// 设置要发送的消息
Channel.send();// 发送消息
}, "消息发送者A").start();
new Thread(() -> {
Message msg = new Message();// 实例化消息主体对象
msg.setInfo("第二个线程消息");// 设置要发送的内容
Channel.setMessage(msg);// 设置要发送的消息
Channel.send();// 发送消息
}, "消息发送者B").start();
new Thread(() -> {
Message msg = new Message();// 实例化消息主体对象
msg.setInfo("第三个线程消息");// 设置要发送的内容
Channel.setMessage(msg);// 设置要发送的消息
Channel.send();// 发送消息
}, "消息发送者C").start();
}
}
class Channel {// 消息发送通道
private static ThreadLocal<Message> THREADLOCAL = new ThreadLocal<Message>();
private Channel() {
}
public static void setMessage(Message m) {
THREADLOCAL.set(m);// 向ThreadLocal中保存数据
}
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;
}
}
#【消息发送者A、消息发送】第一个线程消息
#【消息发送者B、消息发送】第二个线程消息
#【消息发送者C、消息发送】第三个线程消息
每一个线程通过ThreadLocal只允许保存一个数据。
定时器
定时器主要是进行定时任务的处理。Java中提供有定时任务的支持,这种任务的处理只是实现了一种间隔触发的操作。
如果要想实现定时处理操作主要需要有一个定时操作的主体类,以及一个定时任务的控制。可以用两个类实现。
- java.util.TimerTask类:实现定时任务处理;
- java.util.Timer类:进行任务的启动,启动的方法:
|- 任务启动:public void schedule(TimerTask task, long delay);
延迟单位为毫秒
|- 间隔触发:public void scheduleAtFixedRate(TimerTask task, long delay, long period);
package demo;
import java.util.TimerTask;
import java.util.Timer;
class MyTask extends TimerTask {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "、定时任务执行,当前时间:" + System.currentTimeMillis());
}
}
public class JavaDemo1 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTask(), 100, 1000);
}
}
Timer-0、定时任务执行,当前时间:1597697277383
Timer-0、定时任务执行,当前时间:1597697278382
Timer-0、定时任务执行,当前时间:1597697279382
Timer-0、定时任务执行,当前时间:1597697280383
Timer-0、定时任务执行,当前时间:1597697281383
Timer-0、定时任务执行,当前时间:1597697282383
Timer-0、定时任务执行,当前时间:1597697283382
这种定时是由JDK最原始的方式提供的支持,但是实际上开发之中利用此类方式进行的定时处理会非常复杂。
Base64加密工具
加密解密往往都需要一定的规则。加密处理操作类,Base64处理,由两个内部类:
Base64.Encoder
:进行加密处理;- |-加密处理:
public byte[] encode(byte[] src);
Base64.Decoder
:进行解密处理。
|- 解密处理:public byte[] decode(String src);
【范例】加密解密操作:
package demo;
import java.util.Base64;
public class JavaDemoEncode {
public static void main(String[] args) {
String msg = "I miss you~";
String encmsg = new String(Base64.getEncoder().encode(msg.getBytes()));
System.out.println(encmsg);
String decmsg = new String(Base64.getDecoder().decode(encmsg));
System.out.println(decmsg);
}
}
#SSBtaXNzIHlvdX4=
#I miss you~
虽然Base64可以实现加密解密处理,但由于是一个公版的算法,所以如果直接用Base64加密并不安全,最好的做法是使用盐值操作。
package demo;
import java.util.Base64;
public class JavaDemoEncode {
public static void main(String[] args) {
String salt = "what are you doing?" ;
String msg = "I miss you~" + "{" + salt + "}";
String encmsg = new String(Base64.getEncoder().encode(msg.getBytes()));
System.out.println(encmsg);
String decmsg = new String(Base64.getDecoder().decode(encmsg));
System.out.println(decmsg);
}
}
#SSBtaXNzIHlvdX57d2hhdCBhcmUgeW91IGRvaW5nP30=
#I miss you~{what are you doing?}
即便有盐值,实际发现加密的效果也不算很好,最好的做法是多次加密。
package demo;
import java.util.Base64;
class StringUtil{
private static final String SALT = "hello";//公共盐值
private static final int REPEAT = 5;//加密次数
/**
* 加密处理
* @param str 要加密的字符串,需要与盐值整合
* @param repeat 加密的重复次数
* @return 加密后的数据
*/
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);
}
/**
* 进行解密处理
* @param str 要解密的内容
* @return 解密后的原始数据
*/
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 JavaDemoEncode {
public static void main(String[] args) {
String msg = StringUtil.encode("I miss you~") ;
System.out.println(msg);
String dmsg = StringUtil.decode(msg);
System.out.println(dmsg);
}
}
#VmxSR1QxRXlVa2hTYkd4VlltNUNTMVV3WkRSTmJIQkhXbnBHVDAxcldrbFdiVFZQWVZaS05tRjZWVDA9
#I miss you~
最好的做法是使用2~3中加密算法,再找到一些不可以解密的方式。
参考资料:
https://edu.aliyun.com/lesson_1012_9028#_9028