JSON字符串操作
1、创建配置环境
# 引入测试包
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.2.6.RELEASE'
# 创建测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class JsonTest {
@Test
public void test(){
System.out.println("xxxxxxx");
}
}
-
注意
测试的时候需要更改一下idea的设置
2、FastJson简介
# FastJson简介
FastJson是将Java对象转为JSON格式字符串的过程,JavaBean对象,List集合对象,Map集合应用最为广泛。
3、序列化
# Json的数组形式
jsonStr = ['0','1','2','3',4]
-
测试
@Test public void test(){ // 创建数组 String arr [] = {"a", "b", ""}; // 将数组转为JSON形式 Object json = JSON.toJSON(arr); System.out.println("json = " + json); }
# 序列化:将Java对象转为JSON字符串的过程
-
JSON.toJSONString(序列化java对象)
@Test public void test(){ Student student = new Student(); student.setUserName("范浩然"); student.setAge(12); student.setClassName("初二1班"); // 将javaBean对象序列化 String studentInfo = JSON.toJSONString(student); System.out.println("studentInfo = " + studentInfo); // 打印对象信息 System.out.println("student = " + student); }
@Test public void test1(){ Student student = new Student(); student.setUserName("范浩然"); student.setAge(12); student.setClassName("初二1班"); // 序列化集合信息 List<Student> studentList = new ArrayList<>(); studentList.add(student); // 序列化集合信息 String students = JSON.toJSONString(studentList); System.out.println("students = " + students); }
@Test public void test2(){ Student student = new Student(); student.setUserName("范浩然"); student.setAge(12); student.setClassName("初二1班"); HashMap<String, Student> studentMap = new HashMap<>(); studentMap.put("1",student); // 序列化HashMap String studentInfo = JSON.toJSONString(studentMap); System.out.println("studentInfo = " + studentInfo); }
4、反序列化
@Test
public void test3(){
// 反序列化 将Json字符串反序列化为Java对象
String str = "{\"age\":12,\"className\":\"初二1班\",\"userName\":\"范浩然\"}";
// 第一个参数 反序列化的字符串,Java对象的Class对象
Student student = JSON.parseObject(str, Student.class);
System.out.println("student = " + student);
// json对象转为数组
String str3 = " [{\"age\":12,\"className\":\"初二1班\",\"userName\":\"范浩然\"}]";
List<Student> studentList = JSON.parseArray(str3, Student.class);
studentList.forEach(item ->{
System.out.println(item);
});
// json字符串转为集合 转换后集合泛型的class
String str2 = "{\"1\":{\"age\":12,\"className\":\"初二1班\",\"userName\":\"范浩然\"}}";
// 第一个参数 字符串
// 直接进行反序列化 Map集合是没有泛型的,没有泛型的集合是不安全的,转换后的集合必须具有泛型,
// 调用parseObject传递参数,TypeReference类型,在TypeReference类的泛型中,传递转后的Map集合
Map<String,Student> map = JSON.parseObject(str2,new TypeReference<Map<String,Student>>(){});
// 遍历Map
map.entrySet().stream().forEach(item->{
// 遍历键值对
System.out.println("key:"+item.getKey());
System.out.println("value:"+item.getValue());
});
}
5、枚举介绍
@Test
public void test4(){
// 枚举介绍 是进行序列化时 自己可以定义一些特殊的需求
// toJSONString()
// 参数一:要序列化的对象
// 参数二:SerializerFeature枚举类型的可变参数
// 常见的方法
// 1.序列化Null值的字段
Student student = new Student();
student.setClassName("高三一班");
student.setBirthday(new Date());
String studentInfo1 = JSON.toJSONString(student);
System.out.println("studentInfo1 = " + studentInfo1);
// 序列化空字段
String studentInfo2 = JSON.toJSONString(student, SerializerFeature.WriteMapNullValue);
System.out.println("studentInfo2 = " + studentInfo2);
// 序列化字段把值序列化为双引号
String studentInfo3 = JSON.toJSONString(student, SerializerFeature.WriteNullStringAsEmpty);
System.out.println("studentInfo3 = " + studentInfo3);
// 字段为空的时候 序列化为0
String studentInfo4 = JSON.toJSONString(student, SerializerFeature.WriteNullNumberAsZero);
System.out.println("studentInfo4 = " + studentInfo4);
// 序列化 布尔值为null 序列化为false
String studentInfo5 = JSON.toJSONString(student, SerializerFeature.WriteNullBooleanAsFalse);
System.out.println("studentInfo5 = " + studentInfo5);
// 序列化日期
String studentInfo6 = JSON.toJSONString(student, SerializerFeature.WriteDateUseDateFormat);
System.out.println("studentInfo6 = " + studentInfo6);
// 格式化字符串可以接收多个
String s = JSON.toJSONString(student, SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.WriteNullBooleanAsFalse,
SerializerFeature.PrettyFormat);
System.out.println("s = " + s);
}
6、JSONField注解的使用
1、注解
# 若属性是私有的,必须有set方法,否则无法序列化、
1.JSONField可以作用于get/set方法上面
2.配置在字段上面
2、作用于字段上面
@JSONField(name = "username")
private String userName;
@Test
public void test5(){
Student student = new Student();
student.setUserName("范浩然");
student.setClassName("高三一班");
String studentInfo = JSON.toJSONString(student);
System.out.println(studentInfo);
}
3、格式化日期时间
# 使用JSONField格式化日期时间
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@Test
public void test6(){
Student student = new Student();
// 赋值时间数据
student.setCreateTime(new Date());
// 转为JSON字符串
String studentInfo = JSON.toJSONString(student);
System.out.println("studentInfo = " + studentInfo);
}
4、指定字段不序列化
# 可以指定某些字段不序列化
1.serialize = false/deserialize
/**
* 指定年龄这个字段不序列化
*/
@JSONField(serialize = false)
private Integer age;
@Test
public void test7(){
Student student = new Student();
// 虽然给年龄赋值了 但是指定了年龄不序列化 所以结果中年龄只有姓名
student.setAge(32);
student.setUserName("张三");
String studentInfo = JSON.toJSONString(student);
System.out.println("studentInfo = " + studentInfo);
}
5、指定字段顺序
# 可以指定某些字段的一个序列化的顺序
1.ordinal
@JSONField(name = "username",ordinal = 1)
private String userName;
@JSONField(format = "yyyy-MM-dd HH:mm:ss",ordinal = 0)
private Date createTime;
// 首先序列化 创建时间 在序列化姓名
@Test
public void test8(){
Student student = new Student();
student.setUserName("范浩然");
student.setCreateTime(new Date());
String studentInfo = JSON.toJSONString(student);
System.out.println("studentInfo = " + studentInfo);
}
6、自定义序列化内容
# 在fastjson 1.2.16版本之后,JSONField支持新的定制化配置serializeUsing,可以单独对某个类的某个属性定制序列化、反序列化。
指定自定义序列化的内容
/**
* 指定自定义序列化字段
*/
@JSONField(serializeUsing = StudentTypeSerializable.class)
private Boolean status;
创建实现序列化内容的类
/**
* @author hrFan
* @version 1.0
* @description: 自定义序列化内容
* @date 2022/5/9 星期一
*/
public class StudentTypeSerializable implements ObjectSerializer {
/**
*
* @param serializer 序列化器
* @param object 字段的值
* @param fieldName 字段的名称
* @param fieldType 字段的类型
* @param features 特征
* @throws IOException
*/
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
// 获取字段的值
Boolean isStatus = (Boolean) object;
// 判断字段的值
String text = "";
if (isStatus = false){
text = "未启用";
}else {
text = "已启用";
}
// 进行序列化
serializer.write(text);
}
}
测试
@Test
public void test9(){
Student student = new Student();
// 设置字段的值
student.setStatus(false);
String studentInfo = JSON.toJSONString(student);
System.out.println("studentInfo = " + studentInfo);
}
7、自定义反序列化内容
指定反序列化字段
/**
* 指定自定义序列化字段
*/
@JSONField(deserializeUsing = StudentTypeDeSerializable.class)
private Boolean status;
创建反序列化内容的类
/**
* @author hrFan
* @version 1.0
* @description: 自定义序列化内容
* @date 2022/5/9 星期一
*/
public class StudentTypeDeSerializable implements ObjectDeserializer {
/**
*
* @param parser Json解析器
* @param type 字段类型
* @param fieldName 字段名称
* @return 反序列化完成的内容
*/
@Override
public Boolean deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
String isUse = "已启用";
// 获取反序列化的值
String status = parser.getLexer().stringVal();
Boolean b = false;
if (isUse.equals(status)){
b = true;
}
// 返回字段的类型信息
return b;
}
@Override
public int getFastMatchToken() {
return 0;
}
}
测试
@Test
public void test10(){
// 自定义序列化的内容
String studentInfo = "{\"status\":\"已启用\"}";
Student student = JSON.parseObject(studentInfo, Student.class);
System.out.println("student = " + student);
}
3、String字符串操作
1、isBlank(判断字符串是否为空)
# isBlank 空格是非空
1.包含的有空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
@Test
public void test1(){
// 如果为空 返回true 不为空返回false
System.out.println("空格 : " + StringUtils.isBlank(" "));
System.out.println("字符 : " + StringUtils.isBlank("s"));
System.out.println("制表位 : " + StringUtils.isBlank("\t"));
}
2、remove(移除字符)
# 移除单个字符,也可以是字符串
StringUtils.remove(String str, char remove)
StringUtils.remove(String str, String remove);
# 移除开头/结尾匹配的字符序列
StringUtils.removeStart(String str, String remove);
StringUtils.removeStartIgnoreCase(String str, String remove);
StringUtils.removeEnd(String str, String remove);
StringUtils.removeEndIgnoreCase(String str, String remove);
1、移除单个字符串
@Test
public void test2(){
String str = "test";
// 第一个参数 操作的字符串
// 第二个参数 匹配删除的字符
String afterStr = StringUtils.remove(str, "t");
// 原字符串并不会被修改
System.out.println("afterStr = " + afterStr);
}
2、移除匹配的字符串
@Test
public void test3(){
String str = "testtesttestest";
// 移除某个字符串
String afterStr = StringUtils.remove(str, "es");
System.out.println("afterStr = " + afterStr);
}
3、移除首尾匹配的字符串
@Test
public void test4(){
// 移除开头或者结尾匹配的字符序列
String str = "ABCDEFG";
String afterStr1 = StringUtils.removeStart(str, "ab");
String afterStr2 = StringUtils.removeEnd(str, "fg");
System.out.println("-------------------------------------------------");
// 删除忽略大小写
String afterStr3 = StringUtils.removeStartIgnoreCase(str, "ab");
String afterStr4 = StringUtils.removeEndIgnoreCase(str, "fg");
System.out.println("afterStr1 = " + afterStr1);
System.out.println("afterStr2 = " + afterStr2);
System.out.println("afterStr3 = " + afterStr3);
System.out.println("afterStr4 = " + afterStr4);
}
3、trim(去除首尾空白)
@Test
public void test5(){
String str = " demo ";
System.out.println("str = " + str);
// 去除首尾空白的字符
String afterStr = StringUtils.trim(str);
System.out.println("afterStr = " + afterStr);
}
4、strip(去掉首尾匹配字符)
@Test
public void test6(){
String str = "[demoomed]";
System.out.println("str = " + str);
// 去除首尾的[]
// 应用的比较广泛
String stripStr = StringUtils.strip(str, "[]");
System.out.println("stripStr = " + stripStr);
}
5、replace(替换)
# 注意
若被替换的字符串为null,或者被替换的字符或字符序列为null,又或者替换的字符或字符序列为null
此次替换都会被忽略,返回原字符串;
# 替换单个字符或字符序列
replace(String text, String searchString, String replacement);
replace(String text, String searchString, String replacement, int max);max是指替换最大次数,0:不替换,-1:全部替换
replaceChars(String str, char searchChar, char replaceChar);
replaceChars(String str, String searchChars, String replaceChars);
# 只会替换一次,后面即使匹配也不替换
replaceOnce(String text, String searchString, String replacement);
# 指定位置进行字符序列替换,从start索引处开始(包含)到end-1索引处为止进行替换
overlay(String str,String overlay,int start,int end);
# 可以同时替换多个字符序列,一一对应但被替换和替换的字符序列的个数应该对应,否则会报IllegalArgumentException
replaceEach(String text, String[] searchList, String[] replacementList);
StringUtils.replaceEach("test", new String[] { "t", "e" }, new String[] { "T", "E" });
StringUtils.replaceEach("test", null, new String[] { "T", "E" });
test (存在null,不进行替换)
# IllegalArgumentException (被替换和替换的个数不对应)
StringUtils.replaceEach("test", new String[] { "t", "e" }, new String[] { "T", "E", "X" });
# 循环替换--了解即可
replaceEachRepeatedly(String text, String[] searchList, String[]replacementList);
StringUtils.replaceEachRepeatedly("test", new String[] { "e", "E" }, new String[] { "E", "Y" });
tYst (e被替换为E,E又被替换为Y)
1、(replace)替换单个字符或者字符序列
@Test
public void test7(){
String str = "abc123abc";
// 第一个参数 源字符串 第二个参数 需要替换的字符 三个参数 需要替换的字符串
// 第四个参数 max是指替换最大次数,0:不替换,-1:全部替换
String replaceStr1 = StringUtils.replace(str, "abc", "000");
String replaceStr2 = StringUtils.replace(str, "abc", "000",1);
// 当max设置为1时等价于只替换一次
String replaceStr3 = StringUtils.replaceOnce(str, "abc", "000");
System.out.println("replaceStr1 = " + replaceStr1);
System.out.println("replaceStr2 = " + replaceStr2);
System.out.println("replaceStr3 = " + replaceStr3);
}
2、(overlay)替换指定位置字符串序列
@Test
public void test8(){
String str = "system is very good";
// 指定位置开始替换 直接替换除了首尾的字符
String afterStr = StringUtils.overlay(str, "--------", 1, str.length()-1);
System.out.println("afterStr = " + afterStr);
}
3、(replaceEach)批量替换
@Test
public void test9(){
String str = "abcdefgabcdefg";
// 替换多个字符序列
String [] arr1 = { "a", "b"};
String [] arr2 = { "A", "B"};
// 注意 替换的个数一定要一致不然报异常
String afterStr = StringUtils.replaceEach(str, arr1, arr2);
System.out.println("afterStr = " + afterStr);
}
6、(reverse)反转
@Test
public void test10(){
String str1 = "123456789";
String str2 = "1-2-3-4-5-6-7-8-9";
// 字符串反转
String afterStr1 = StringUtils.reverse(str1);
// 根据分隔符反转
String afterStr2 = StringUtils.reverseDelimited(str2,'-');
System.out.println("afterStr1 = " + afterStr1);
System.out.println("afterStr2 = " + afterStr2);
}
7、(substring)截取
# 截取
1.从左到对右下标默认从0开始,从右往左下标默认从-1开始
@Test
public void test11(){
String str1 = "0123456789";
// 从第五个位置开始截取
String afterBefore1 = StringUtils.substring(str1, 5);
// 指定截取的开始位置和结束位置
String afterBefore2 = StringUtils.substring(str1, 0, 5);
System.out.println("afterBefore1 = " + afterBefore1);
System.out.println("afterBefore2 = " + afterBefore2);
}
# 根据指定的分隔符进行截取
# substringAfter
从分隔符第一次出现的位置向后截取
# substringBefore
从分隔符第一次出现的位置向前截取
# substringAfterLast
从分隔符最后一次出现的位置向后截取
# substringBeforeLast
从分隔符最后一次出现的位置向前截取
# substringBetween
截取指定标记字符之间的字符序列
@Test
public void test12(){
String str = "ab-cd-ef-gh-ij-kl-mn-op-qr";
// 从分隔符第一次出现的位置向后截取
String afterStr1 = StringUtils.substringAfter(str, "-");
String afterStr2 = StringUtils.substringBefore(str, "-");
System.out.println("afterStr1 = " + afterStr1);
System.out.println("afterStr2 = " + afterStr2);
System.out.println("------------------------------------------------");
// 从分隔符最后一次出现的位置向前或者向后截取
String afterStr3 = StringUtils.substringAfterLast(str, "-");
String afterStr4 = StringUtils.substringBeforeLast(str, "-");
System.out.println("afterStr3 = " + afterStr3);
System.out.println("afterStr4 = " + afterStr4);
System.out.println("------------------------------------------------");
// 截取指定标记字符之间的序列
String str2 = "A00000000000000000000000000000000000000A";
String afterStr5 = StringUtils.substringBetween(str2, "A");
System.out.println("afterStr5 = " + afterStr5);
}
8、(containsOnly)包含
# 包含
判断字符串中的字符是否都是出自所指定的字符数组或字符串 StringUtils.containsOnly(str, validChars);
需要注意的是:前面的字符是否都出自后面的参数中,也是拆为数组来比较
@Test
public void test13(){
String str = "Happiness is a way station between too much and too little";
// 注意 他是拆分成字符数组比较的(所以只要有to这个字符串序列 就会匹配成功) 注意顺序
// 判断字符序列中是否包含一个字符或一个字符序列
// str中是否包含to这个字符序列
boolean isExistTo1 = StringUtils.containsOnly("to",str);
boolean isExistTo2 = StringUtils.containsOnly("ato",str);
System.out.println("isExistToo1 = " + isExistTo1);
System.out.println("isExistToo2 = " + isExistTo2);
// 用于检测字符串是否以指定的前缀开始
boolean isHappinessPrefix = StringUtils.startsWith(str,"Happiness");
System.out.println("isHappinessPrefix = " + isHappinessPrefix);
}
9、(indexOf)查找字符索引
# indexOf
返回在字符串中第一次出现的位置,如果没有在字符串中出现,则返回-1
# lastIndexOf
返回在字符串中最后一次出现的索引
# indexOfAny
返回字符数组第一次出现在字符串中的位置
# indexOfAnyBut
子字符串与主字符串不匹配部分的位置
StringUtils.indexOfAnyBut("sdsfhhl0","h");//结果是0
StringUtils.indexOfAnyBut("sdsfhhl0","s");//结果是1
StringUtils.indexOfAnyBut("aa","aa");//结果是-1
# indexOfDifference
统计两个字符串共有的字符个数
# difference
去掉两个字符串相同的字符以后的字符串
@Test
public void test14(){
String str = "hello,world";
// 查找字符出现的位置
int index1 = StringUtils.indexOf(str, "l");
System.out.println("index1 = " + index1);
// 查找字符最后出现的索引位置
int index2 = StringUtils.lastIndexOf(str,"l");
System.out.println("index2 = " + index2);
// 查找字符串第一次出现的索引的位置
int index3 = StringUtils.indexOfAny(str, "l");
System.out.println("index3 = " + index3);
// 查找字符和字符串不匹配的开始位置
int index4 = StringUtils.indexOfAnyBut(str,"we");
System.out.println("index4 = " + index4);
// 统计两个字符串开始共有的字符个数
int number = StringUtils.indexOfDifference(str,"hello");
System.out.println("number = " + number);
// 去除两个字符串开始共有的部门
String afterStr = StringUtils.difference(str,"hello,java");
System.out.println("afterStr = " + afterStr);
}
10、首字母大小写
# capitalize
首字母大写
# uncapitalize
首字母小写
@Test
public void test15(){
String str = "fhr";
System.out.println("str = " + str);
// 首字母变为大写
String capitalize = StringUtils.capitalize(str);
System.out.println("首字母大写 = " + capitalize);
// 首字母变为小写
String uncapitalize = StringUtils.uncapitalize(capitalize);
System.out.println("首字母小写 = " + uncapitalize);
// 全部变为大写
String upperCase = StringUtils.upperCase(capitalize);
System.out.println("全部变为大写 = " + upperCase);
// 全部变为小写
String lowerCase = StringUtils.lowerCase(upperCase);
System.out.println("全部变为小写 = " + lowerCase);
}