前言
不是我封装的,是我从别人那找的,然后作分析。
提示:以下是本篇文章正文内容,下面案例可供参考
一、jwt工具类
使用:
package com.heima.utils.common;
import io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class AppJwtUtil {
// TOKEN的有效期一天(S)
private static final int TOKEN_TIME_OUT = 3_600;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
// 生产ID
public static String getToken(Long id){
Map<String, Object> claimMaps = new HashMap<>();
claimMaps.put("id",id);
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //签发时间
.setSubject("system") //说明
.setIssuer("jjpzh") //签发者信息
.setAudience("app") //接收用户
.compressWith(CompressionCodecs.GZIP) //数据压缩方式
.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
.addClaims(claimMaps) //cla信息
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws<Claims> getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息
*
* @param token
* @return
*/
public static Claims getClaimsBody(String token) {
try {
return getJws(token).getBody();
}catch (ExpiredJwtException e){
return null;
}
}
/**
* 获取hearder body信息
*
* @param token
* @return
*/
public static JwsHeader getHeaderBody(String token) {
return getJws(token).getHeader();
}
/**
* 是否过期
*
* @param claims
* @return -1:有效,0:有效,1:过期,2:过期
*/
public static int verifyToken(Claims claims) {
if(claims==null){
return 1;
}
try {
claims.getExpiration()
.before(new Date());
// 需要自动刷新TOKEN
if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
return -1;
}else {
return 0;
}
} catch (ExpiredJwtException ex) {
return 1;
}catch (Exception e){
return 2;
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static void main(String[] args) {
/* Map map = new HashMap();
map.put("id","11");*/
System.out.println(AppJwtUtil.getToken(1102L));
//根据上面的输出的token获取claims
Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDMAwE_6JzDJYtZCu_URNDXQgY5EBL6d-rHHLb2WG-8JodVqASOafKAUn2QFuTILloqP7HTTgzJVig64QVmSshY4oL2Pnw2j4223F5M8dn64c66bk76Ri-23vcpZSr7O4QY_r9ATyrF3uDAAAA.dkbs7Qz0SUBunCU1IcBJIrx4Sz70RRAtRYA6kHjhyauLm9JGNviVzOpdEXgyXj31dJflSnkPRtZxjnec8vRGbA");
Claims claims = jws.getBody();
System.out.println(claims.get("id"));
}
}
二.计算两个字符串的相似度
用法参考代码中的主方法
package com.heima.utils.common;
import java.text.NumberFormat;
import java.util.Locale;
public class Compute {
public static void main(String[] args) {
String str1 = "蜂蜜吃我吗";
String str2 = "我吃蜂蜜";
double ss = SimilarDegree(str1, str2);
System.out.println(ss);
}
/*
* 计算相似度
* */
public static double SimilarDegree(String strA, String strB) {
String newStrA = removeSign(strA);
String newStrB = removeSign(strB);
//让newStrA的长度大于newStrB
if (newStrA.length() < newStrB.length()) {
String temp = newStrA;
newStrA = newStrB;
newStrB = temp;
}
//用较大的字符串长度作为分母,相似子串作为分子计算出字串相似度
int temp = Math.max(newStrA.length(), newStrB.length());
int temp2 = longestCommonSubstring(newStrA, newStrB).length();
return temp2 * 1.0 / temp;
}
/*
* 将字符串的所有数据依次写成一行
* */
public static String removeSign(String str) {
StringBuffer sb = new StringBuffer();
//遍历字符串str,如果是汉字数字或字母,则追加到ab上面
for (char item : str.toCharArray()) {
if (charReg(item)) {
sb.append(item);
}
}
return sb.toString();
}
/*
* 判断字符是否为汉字,数字和字母,
* 因为对符号进行相似度比较没有实际意义,故符号不加入考虑范围。
* */
public static boolean charReg(char charValue) {
return (charValue >= 0x4E00 && charValue <= 0X9FA5) || (charValue >= 'a' && charValue <= 'z')
|| (charValue >= 'A' && charValue <= 'Z') || (charValue >= '0' && charValue <= '9');
}
/*
* 求公共子串,采用动态规划算法。
* 其不要求所求得的字符在所给的字符串中是连续的。
*
* */
public static String longestCommonSubstring(String strA, String strB) {
char[] chars_strA = strA.toCharArray();
char[] chars_strB = strB.toCharArray();
int m = chars_strA.length;
int n = chars_strB.length;
/*
* 初始化矩阵数据,matrix[0][0]的值为0,
* 如果字符数组chars_strA和chars_strB的对应位相同,则matrix[i][j]的值为左上角的值加1,
* 否则,matrix[i][j]的值等于左上方最近两个位置的较大值,
* 矩阵中其余各点的值为0.
*/
int[][] matrix = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (chars_strA[i - 1] == chars_strB[j - 1]) {
matrix[i][j] = matrix[i - 1][j - 1] + 1;
} else {
matrix[i][j] = Math.max(matrix[i][j - 1], matrix[i - 1][j]);
}
}
}
/*
* 矩阵中,如果matrix[m][n]的值不等于matrix[m-1][n]的值也不等于matrix[m][n-1]的值,
* 则matrix[m][n]对应的字符为相似字符元,并将其存入result数组中。
*
*/
char[] result = new char[matrix[m][n]];
int currentIndex = result.length - 1;
while (matrix[m][n] != 0) {
if (matrix[n] == matrix[n - 1]){
n--;
} else if (matrix[m][n] == matrix[m - 1][n]){
m--;
}else {
result[currentIndex] = chars_strA[m - 1];
currentIndex--;
n--;
m--;
}
}
return new String(result);
}
/*
* 结果转换成百分比形式
* */
public static String similarityResult(double resule) {
return NumberFormat.getPercentInstance(new Locale("en ", "US ")).format(resule);
}
}
三.日期工具类
package com.heima.utils.common;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtils {
public static String DATE_FORMAT = "yyyy-MM-dd";
public static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_TIME_STAMP_FORMATE = "yyyyMMddHHmmss";
//2019年07月09日
public static String DATE_FORMAT_CHINESE = "yyyy年M月d日";
//2019年07月09日 14:00:32
public static String DATE_TIME_FORMAT_CHINESE = "yyyy年M月d日 HH:mm:ss";
/**
* 获取当前日期
*
* @return
*/
public static String getCurrentDate() {
String datestr = null;
SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
datestr = df.format(new Date());
return datestr;
}
/**
* 获取当前日期时间
*
* @return
*/
public static String getCurrentDateTime() {
String datestr = null;
SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
datestr = df.format(new Date());
return datestr;
}
/**
* 获取当前日期时间
*
* @return
*/
public static String getCurrentDateTime(String Dateformat) {
String datestr = null;
SimpleDateFormat df = new SimpleDateFormat(Dateformat);
datestr = df.format(new Date());
return datestr;
}
/**
* 将日期格式日期转换为字符串格式
*
* @param date
* @return
*/
public static String dateToString(Date date) {
String datestr = null;
SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
datestr = df.format(date);
return datestr;
}
/**
* 将日期格式日期转换为字符串格式 自定義格式
*
* @param date
* @param dateformat
* @return
*/
public static String dateToString(Date date, String dateformat) {
String datestr = null;
SimpleDateFormat df = new SimpleDateFormat(dateformat);
datestr = df.format(date);
return datestr;
}
/**
* 获取日期的DAY值
*
* @param date 输入日期
* @return
*/
public static int getDayOfDate(Date date) {
int d = 0;
Calendar cd = Calendar.getInstance();
cd.setTime(date);
d = cd.get(Calendar.DAY_OF_MONTH);
return d;
}
/**
* 获取日期的MONTH值
*
* @param date 输入日期
* @return
*/
public static int getMonthOfDate(Date date) {
int m = 0;
Calendar cd = Calendar.getInstance();
cd.setTime(date);
m = cd.get(Calendar.MONTH) + 1;
return m;
}
/**
* 获取日期的YEAR值
*
* @param date 输入日期
* @return
*/
public static int getYearOfDate(Date date) {
int y = 0;
Calendar cd = Calendar.getInstance();
cd.setTime(date);
y = cd.get(Calendar.YEAR);
return y;
}
/**
* 获取星期几
*
* @param date 输入日期
* @return
*/
public static int getWeekOfDate(Date date) {
int wd = 0;
Calendar cd = Calendar.getInstance();
cd.setTime(date);
wd = cd.get(Calendar.DAY_OF_WEEK) - 1;
return wd;
}
/**
* 判断是否是闰年
*
* @param date 输入日期
* @return 是true 否false
*/
public static boolean isLeapYear(Date date) {
Calendar cd = Calendar.getInstance();
cd.setTime(date);
int year = cd.get(Calendar.YEAR);
if (year % 4 == 0 && year % 100 != 0 | year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
* 根据整型数表示的年月日,生成日期类型格式
*
* @param year 年
* @param month 月
* @param day 日
* @return
*/
public static Date getDateByYMD(int year, int month, int day) {
Calendar cd = Calendar.getInstance();
cd.set(year, month - 1, day);
return cd.getTime();
}
/**
* 计算 fromDate 到 toDate 相差多少年
*
* @param fromDate
* @param toDate
* @return 年数
*/
public static int getYearByMinusDate(Date fromDate, Date toDate) {
Calendar df = Calendar.getInstance();
df.setTime(fromDate);
Calendar dt = Calendar.getInstance();
dt.setTime(toDate);
return dt.get(Calendar.YEAR) - df.get(Calendar.YEAR);
}
/**
* 计算 fromDate 到 toDate 相差多少个月
*
* @param fromDate
* @param toDate
* @return 月数
*/
public static int getMonthByMinusDate(Date fromDate, Date toDate) {
Calendar df = Calendar.getInstance();
df.setTime(fromDate);
Calendar dt = Calendar.getInstance();
dt.setTime(toDate);
return dt.get(Calendar.YEAR) * 12 + dt.get(Calendar.MONTH) -
(df.get(Calendar.YEAR) * 12 + df.get(Calendar.MONTH));
}
/**
* 计算年龄
*
* @param birthday 生日日期
* @param calcDate 要计算的日期点
* @return
*/
public static int calcAge(Date birthday, Date calcDate) {
int cYear = DateUtils.getYearOfDate(calcDate);
int cMonth = DateUtils.getMonthOfDate(calcDate);
int cDay = DateUtils.getDayOfDate(calcDate);
int bYear = DateUtils.getYearOfDate(birthday);
int bMonth = DateUtils.getMonthOfDate(birthday);
int bDay = DateUtils.getDayOfDate(birthday);
if (cMonth > bMonth || (cMonth == bMonth && cDay > bDay)) {
return cYear - bYear;
} else {
return cYear - 1 - bYear;
}
}
/**
* 从身份证中获取出生日期
*
* @param idno 身份证号码
* @return
*/
public static String getBirthDayFromIDCard(String idno) {
Calendar cd = Calendar.getInstance();
if (idno.length() == 15) {
cd.set(Calendar.YEAR, Integer.valueOf("19" + idno.substring(6, 8))
.intValue());
cd.set(Calendar.MONTH, Integer.valueOf(idno.substring(8, 10))
.intValue() - 1);
cd.set(Calendar.DAY_OF_MONTH,
Integer.valueOf(idno.substring(10, 12)).intValue());
} else if (idno.length() == 18) {
cd.set(Calendar.YEAR, Integer.valueOf(idno.substring(6, 10))
.intValue());
cd.set(Calendar.MONTH, Integer.valueOf(idno.substring(10, 12))
.intValue() - 1);
cd.set(Calendar.DAY_OF_MONTH,
Integer.valueOf(idno.substring(12, 14)).intValue());
}
return DateUtils.dateToString(cd.getTime());
}
/**
* 在输入日期上增加(+)或减去(-)天数
*
* @param date 输入日期
* @param iday 要增加或减少的天数
*/
public static Date addDay(Date date, int iday) {
Calendar cd = Calendar.getInstance();
cd.setTime(date);
cd.add(Calendar.DAY_OF_MONTH, iday);
return cd.getTime();
}
/**
* 在输入日期上增加(+)或减去(-)月份
*
* @param date 输入日期
* @param imonth 要增加或减少的月分数
*/
public static Date addMonth(Date date, int imonth) {
Calendar cd = Calendar.getInstance();
cd.setTime(date);
cd.add(Calendar.MONTH, imonth);
return cd.getTime();
}
/**
* 在输入日期上增加(+)或减去(-)年份
*
* @param date 输入日期
* @param iyear 要增加或减少的年数
*/
public static Date addYear(Date date, int iyear) {
Calendar cd = Calendar.getInstance();
cd.setTime(date);
cd.add(Calendar.YEAR, iyear);
return cd.getTime();
}
/**
* @param args
*/
public static void main(String[] args) {
//测试getCurrentDate() 获取当前日期
System.out.println("当前日期:" + DateUtils.getCurrentDate());//当前日期:2012-12-12
//测试getCurrentDateTime() 获取当前日期时间
System.out.println("当前日期时间:" + DateUtils.getCurrentDateTime());//当前日期时间:2012-12-12 14:12:12
//测试getCurrentDateTime(String format) 获取当前日期时间
System.out.println("当前日期时间:" + DateUtils.getCurrentDateTime("yyyy-MM-dd HH"));//当前日期时间:2012-12-12 14
//测试dateToString(Date) 日期转换为字符串
System.out.println("日期转换为字符串:" + DateUtils.dateToString(new Date()));//日期转换为字符串:2012-12-12
//测试dateToString(Date, String) 日期转换为字符串
System.out.println("日期转换为字符串:" + DateUtils.dateToString(new Date(), "yyyy-MM-dd"));//日期转换为字符串:2012-12-12
//测试getDayOfDate(Date) 获取日期是几号
System.out.println("获取日期是星期几:" + DateUtils.getDayOfDate(new Date()));//获取日期是几号:14
//测试getMonthOfDate(Date) 获取日期是几月
System.out.println("获取日期是几月:" + DateUtils.getMonthOfDate(new Date()));//获取日期是几月:12
//测试getYearOfDate(Date) 获取日期是几年
System.out.println("获取日期是几年:" + DateUtils.getYearOfDate(new Date()));//获取日期是几年:2012
//测试getWeekOfDate(Date) 获取日期是星期几
System.out.println("获取日期是一年中的第几周:" + DateUtils.getWeekOfDate(new Date())); //获取日期是星期几:1
//测试isLeapYear(Date) 判断日期所在年份是否是闰年
System.out.println("判断日期所在年份是否是闰年:" + DateUtils.isLeapYear(new Date()));//判断日期所在年份是否是闰年:false
//测试getDateByYMD(int, int, int) 根据年月日获取日期
System.out.println("根据年月日获取日期:" + DateUtils.getDateByYMD(2012, 12, 12));//根据年月日获取日期:2012-12-12
//测试getYearByMinusDate(Date,Date) 获取两个日期相差的年数
System.out.println("获取两个日期相差的年数:" + DateUtils.getYearByMinusDate(new Date(), DateUtils.getDateByYMD(2011, 12, 12)));//获取两个日期相差的年数:1
//测试getMonthByMinusDate(Date,Date) 获取两个日期相差的月数
System.out.println("获取两个日期相差的月数:" + DateUtils.getMonthByMinusDate(new Date(), DateUtils.getDateByYMD(2011, 12, 12)));//获取两个日期相差的月数:12
//剩下的测试不写了自己看吧
}
}
四.DES加密算法
package com.heima.utils.common;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class DESUtils {
public static final String key = "12345678";
/**
* 加密
* @param content
* @param keyBytes
* @return
*/
private static byte[] encrypt(byte[] content, byte[] keyBytes) {
try {
DESKeySpec keySpec = new DESKeySpec(keyBytes);
String algorithm = "DES";//指定使什么样的算法
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
SecretKey key = keyFactory.generateSecret(keySpec);
String transformation = "DES/CBC/PKCS5Padding"; //用什么样的转型方式
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(keySpec.getKey()));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
* @param content
* @param keyBytes
* @return
*/
private static byte[] decrypt(byte[] content, byte[] keyBytes) {
try {
DESKeySpec keySpec = new DESKeySpec(keyBytes);
String algorithm = "DES";
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm );
SecretKey key = keyFactory.generateSecret(keySpec);
String transformation = "DES/CBC/PKCS5Padding";
Cipher cipher = Cipher.getInstance(transformation );
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(keyBytes));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 二进制转16进制
* @param bytes
* @return
*/
private static String byteToHexString(byte[] bytes) {
StringBuffer sb = new StringBuffer();
String sTemp;
for (int i = 0; i<bytes.length; i++) {
sTemp = Integer.toHexString(0xFF & bytes[i]);
if (sTemp.length() < 2) {
sb.append(0);
}
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
/**
* 16进制字符串转bytes
* @param hex
* @return
*/
public static byte[] hexStringToByte(String hex) {
int len = 0;
int num=0;
//判断字符串的长度是否是两位
if(hex.length()>=2){
//判断字符喜欢是否是偶数
len=(hex.length() / 2);
num = (hex.length() % 2);
if (num == 1) {
hex = "0" + hex;
len=len+1;
}
}else{
hex = "0" + hex;
len=1;
}
byte[] result = new byte[len];
char[] achar = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
}
return result;
}
private static int toByte(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
private static byte[] hexToByteArr(String strIn) {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i = i + 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}
/**
* 加密
* @param pass
* @return
*/
public static String encode(String pass){
return byteToHexString(encrypt(pass.getBytes(), key.getBytes()));
}
/**
* 解密
* @param passcode
* @return
*/
public static String decode(String passcode){
return byteToHexString(decrypt(hexToByteArr(passcode), key.getBytes()));
}
public static void main(String[] args) {
String content = "password111111111111111";
System.out.println("加密前 "+ byteToHexString(content.getBytes()));
byte[] encrypted = encrypt(content.getBytes(), key.getBytes());
System.out.println("加密后:"+ byteToHexString(encrypted));
byte[] decrypted=decrypt(encrypted, key.getBytes());
System.out.println("解密后:"+ byteToHexString(decrypted));
System.out.println(encode(content));
String s = new String(hexStringToByte(decode("159CF72C0BD2A8183D536215768C2E91556D77642F214E34")));
System.out.println(s);
}
}
五.Jdk序列化工具
package com.heima.utils.common;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* jdk序列化
*/
public class JdkSerializeUtil {
/**
* 序列化
* @param obj
* @param <T>
* @return
*/
public static <T> byte[] serialize(T obj) {
if (obj == null){
throw new NullPointerException();
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
return bos.toByteArray();
} catch (Exception ex) {
ex.printStackTrace();
}
return new byte[0];
}
/**
* 反序列化
* @param data
* @param clazz
* @param <T>
* @return
*/
public static <T> T deserialize(byte[] data, Class<T> clazz) {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
try {
ObjectInputStream ois = new ObjectInputStream(bis);
T obj = (T)ois.readObject();
return obj;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
六.Md5加密
package com.heima.utils.common;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/**
* MD5加密
* @param str
* @return
*/
public final static String encode(String str) {
try {
//创建具有指定算法名称的摘要
MessageDigest md = MessageDigest.getInstance("MD5");
//使用指定的字节数组更新摘要
md.update(str.getBytes());
//进行哈希计算并返回一个字节数组
byte mdBytes[] = md.digest();
String hash = "";
//循环字节数组
for (int i = 0; i < mdBytes.length; i++) {
int temp;
//如果有小于0的字节,则转换为正数
if (mdBytes[i] < 0)
temp = 256 + mdBytes[i];
else
temp = mdBytes[i];
if (temp < 16)
hash += "0";
//将字节转换为16进制后,转换为字符串
hash += Integer.toString(temp, 16);
}
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static String encodeWithSalt(String numStr, String salt) {
return encode(encode(numStr) + salt);
}
public static void main(String[] args) {
System.out.println(encode("test"));//e10adc3949ba59abbe56e057f20f883e
System.out.println(encodeWithSalt("123456","123456"));//5f1d7a84db00d2fce00b31a7fc73224f
}
}
七.Protostuff序列化工具
import com.heima.model.wemedia.pojos.WmNews;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
public class ProtostuffUtil {
/**
* 序列化
* @param t
* @param <T>
* @return
*/
public static <T> byte[] serialize(T t){
Schema schema = RuntimeSchema.getSchema(t.getClass());
return ProtostuffIOUtil.toByteArray(t,schema,
LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
}
/**
* 反序列化
* @param bytes
* @param c
* @param <T>
* @return
*/
public static <T> T deserialize(byte []bytes,Class<T> c) {
T t = null;
try {
t = c.newInstance();
Schema schema = RuntimeSchema.getSchema(t.getClass());
ProtostuffIOUtil.mergeFrom(bytes,t,schema);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return t;
}
/**
* jdk序列化与protostuff序列化对比
* @param args
*/
public static void main(String[] args) {
long start =System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
WmNews wmNews =new WmNews();
JdkSerializeUtil.serialize(wmNews);
}
System.out.println(" jdk 花费 "+(System.currentTimeMillis()-start));
start =System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
WmNews wmNews =new WmNews();
ProtostuffUtil.serialize(wmNews);
}
System.out.println(" protostuff 花费 "+(System.currentTimeMillis()-start));
}
}
八.敏感词工具类
package com.heima.utils.common;
import java.util.*;
public class SensitiveWordUtil {
public static Map<String, Object> dictionaryMap = new HashMap<>();
/**
* 生成关键词字典库
* @param words
* @return
*/
public static void initMap(Collection<String> words) {
if (words == null) {
System.out.println("敏感词列表不能为空");
return ;
}
// map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字)
Map<String, Object> map = new HashMap<>(words.size());
// 遍历过程中当前层次的数据
Map<String, Object> curMap = null;
Iterator<String> iterator = words.iterator();
while (iterator.hasNext()) {
String word = iterator.next();
curMap = map;
int len = word.length();
for (int i =0; i < len; i++) {
// 遍历每个词的字
String key = String.valueOf(word.charAt(i));
// 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据
Map<String, Object> wordMap = (Map<String, Object>) curMap.get(key);
if (wordMap == null) {
// 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志)
wordMap = new HashMap<>(2);
wordMap.put("isEnd", "0");
curMap.put(key, wordMap);
}
curMap = wordMap;
// 如果当前字是词的最后一个字,则将isEnd标志置1
if (i == len -1) {
curMap.put("isEnd", "1");
}
}
}
dictionaryMap = map;
}
/**
* 搜索文本中某个文字是否匹配关键词
* @param text
* @param beginIndex
* @return
*/
private static int checkWord(String text, int beginIndex) {
if (dictionaryMap == null) {
throw new RuntimeException("字典不能为空");
}
boolean isEnd = false;
int wordLength = 0;
Map<String, Object> curMap = dictionaryMap;
int len = text.length();
// 从文本的第beginIndex开始匹配
for (int i = beginIndex; i < len; i++) {
String key = String.valueOf(text.charAt(i));
// 获取当前key的下一个节点
curMap = (Map<String, Object>) curMap.get(key);
if (curMap == null) {
break;
} else {
wordLength ++;
if ("1".equals(curMap.get("isEnd"))) {
isEnd = true;
}
}
}
if (!isEnd) {
wordLength = 0;
}
return wordLength;
}
/**
* 获取匹配的关键词和命中次数
* @param text
* @return
*/
public static Map<String, Integer> matchWords(String text) {
Map<String, Integer> wordMap = new HashMap<>();
int len = text.length();
for (int i = 0; i < len; i++) {
int wordLength = checkWord(text, i);
if (wordLength > 0) {
String word = text.substring(i, i + wordLength);
// 添加关键词匹配次数
if (wordMap.containsKey(word)) {
wordMap.put(word, wordMap.get(word) + 1);
} else {
wordMap.put(word, 1);
}
i += wordLength - 1;
}
}
return wordMap;
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("法轮");
list.add("法轮功");
list.add("冰毒");
initMap(list);
String content="我是一个好人,并不会卖冰毒,也不操练法轮功,我真的不卖冰毒";
Map<String, Integer> map = matchWords(content);
System.out.println(map);
}
}