在日常工作中,我们经常要使用到一些开源工具包,比如String,Date等等。有时候我们并不清楚有这些工具类的存在,造成在开发过程中重新实现导致时间浪费,且开发的代码质量不佳。而apache其实已经提供了系列的工具包给我们使用,只是大多数人,平时没有注意到。这个系列我将带领大家熟悉这些常用的工具包,让大家熟悉Apache都给我们提供了那些常用的工具类和方法……
工具名称 | 作用 |
---|---|
BeanUtils | 对Java Bean进行各种操作,复制对象,属性 |
Codec | 处理常用的编码,解码 |
Collections | 扩展Java集合框架的操作 |
I/O | 输入输出工具的封装 |
Lang | java基本对象(java.lang)方法的工具类包 |
BeanUtils 提供对 Java 反射和自省 API 的包装,其主要目的是利用反射机制对 JavaBean 的属性进行处理。对于JavaBean进行各种操作,克隆对象,属性等等.
例如
BeanUtils可以对javaBean的属性进行赋值。
BeanUtils可以将一个MAP集合的数据拷贝到一个javabean对象中。
BeanUtils可以对javaBean的对象进行赋值。
常用方法 | 描述 |
---|---|
copyProperties(Object dest, Object orig) | 对象拷贝 |
copyProperty(Object bean, String name, Object value) | 指定属性拷贝到指定的对象中 |
cloneBean(Object bean) | 对象的克隆 |
populate(Object bean, Map |
将map数据拷贝到javabean中(map的key要与javabean的属性名称一致) |
setProperty(Object bean, String name, Object value) | 设置指定属性的值 |
1) BeanUtils.cloneBean()
我们知道,一个 JavaBean 通常包含了大量的属性,很多情况下,对 JavaBean 的处理导致大量 get/set 代码堆积,增加了代码长度和阅读代码的难度
// 新创建一个普通Java Bean,用来作为被克隆的对象
public class Person {
private String name = "";
private String email = "";
private int age;
//省略 set,get方法
}
Person person = new Person();
person.setName("tom");
person.setAge(21);
try {
//克隆
Person person2 = (Person) BeanUtils.cloneBean(person);
System.out.println(person2.getName() + ">>" + person2.getAge());
} catch (
IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// 原理也是通过Java的反射机制来做的。
// 2、 将一个Map对象转化为一个Bean
// 这个Map对象的key必须与Bean的属性相对应。
Map map = new HashMap();
map.put("name", "tom");
map.put("email", "tom@");
map.put("age", "21");
//将map转化为一个Person对象
Person person = new Person();
BeanUtils.populate(person, map);
// 通过上面的一行代码,此时person的属性就已经具有了上面所赋的值了。
// 将一个Bean转化为一个Map对象了,如下:
Map map = BeanUtils.describe(person)
2) BeanUtils.copyProperties()
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, (Class)null, (String[])null);
}
如果你有两个具有很多相同属性的 JavaBean,传统的方式是使用类似下面的语句对属性逐个赋值:
Person p = new Person();
p.setName("Ensk");
p.setAge(18);
p.setGender(1);
p.setMajor("Literature");
Teacher t = new Teacher();
t.setName(p.getName());
t.setAge(p.getAge());
t.setGender(p.getGender());
t.setMajor(p.getMajor());
而使用 BeanUtils 后,代码就大大改观了,如下所示:
Person p = new Person();
p.setName("Ensk");
p.setAge(18);
p.setGender(1);
p.setMajor("Literature");
Teacher t = new Teacher();
BeanUtils.copyProperties(p,t);
如果 Person 和 Teacher 间存在名称不相同的属性,则 BeanUtils 不对这些属性进行处理,需要程序手动处理
3) 其它示例
@Test
public void BeanUtilsTest() throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "张三");
map.put("age", 12);
map.put("sex", "男");
// 将map数据拷贝到Student中
Student stu= new Student();
BeanUtils.populate(stu, map);
//Student [name=张三, age=12, sex=男]
System.out.println(stu);
// 对象的拷贝
Student stu1 = new Student ();
BeanUtils.copyProperties(stu , stu1 );
//Student [name=张三, age=12, sex=男]
System.out.println(stu1);
// 拷贝指定的属性
Student stu2 = new Student ();
BeanUtils.copyProperty(stu2 , "name", "李四");
// Student [name=李四, age=0, sex=null]
System.out.println(stu2 );
// 设置指定的属性
BeanUtils.setProperty(stu2, "sex", "女");
// Student [name=李四, age=0, sex=女]
System.out.println((stu2);
// 克隆对象
Object object = BeanUtils.cloneBean(stu2);
// Animal [name=李四, age=0, sex=女]
System.out.println(object);
}
注意事项:BeanUtils在进行数据拷贝中,不管数据是否有值,会直接覆盖,这样就会存在有些需求无法满足的情况,不如说当拷贝的值为null时,不允许覆盖,可以进行如下操作:
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
BeanUtils.copyProperties(源对象,新对象,getNullPropertyNames (源对象));
codec支持的编码格式常见有plain、json、json_lines等。
提供了一些公共的编解码实现,比如Base64, Hex, MD5,Phonetic and URLs等等。
//Base64编解码
private static String encodeTest(String str) {
Base64 base64 = new Base64();
try {
str = base64.encodeToString(str.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("Base64 编码后:" + str);
return str;
}
private static void decodeTest(String str) {
Base64 base64 = new Base64();
//str = Arrays.toString(Base64.decodeBase64(str));
str = new String(Base64.decodeBase64(str));
System.out.println("Base64 解码后:" + str);
}
对java.util的扩展封装,用于操作集合类,如list,set。提供的所有方法都是静态的。
org.apache.commons.collections – Commons Collections自定义的一组公用的接口和工具类
org.apache.commons.collections.bag – 实现Bag接口的一组类
org.apache.commons.collections.bidimap – 实现BidiMap系列接口的一组类
org.apache.commons.collections.buffer – 实现Buffer接口的一组类
org.apache.commons.collections.collection – 实现java.util.Collection接口的一组类
org.apache.commons.collections.comparators – 实现java.util.Comparator接口的一组类
org.apache.commons.collections.functors – Commons Collections自定义的一组功能类
org.apache.commons.collections.iterators – 实现java.util.Iterator接口的一组类
org.apache.commons.collections.keyvalue – 实现集合和键/值映射相关的一组类
org.apache.commons.collections.list – 实现java.util.List接口的一组类
org.apache.commons.collections.map – 实现Map系列接口的一组类
org.apache.commons.collections.set – 实现Set系列接口的一组类
1) sort方法
sort方法的使用(对集合进行排序,默认按照升序排序,列表中所有元素必须实现Comparable接口)
//需求:对已知集合list进行排序
public class TestCollection {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("c");
list.add("d");
list.add("b");
list.add("a");
Collections.sort(list);
System.out.println(list);
}
}
//结果:[a, b, c, d]
2) reverse方法
reverse方法的使用(对集合中元素进行反转)
//需求:对已知集合list进行反转
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
Collections.reverse(list);
System.out.println(list);
}
}
//运行结果:[f, e, d, c, b, a]
3) shuffle方法的使用(对集合中元素进行随机排序)
//需求:对已知集合list进行随机排序
public class TestCollection {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("c");
list.add("d");
list.add("b");
list.add("a");
Collections.shuffle(list);
System.out.println(list);
}
}
//[d, c, a, b]
4) fill(list list,Object o)方法的适用(用对象0替换list中的所有元素)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
System.out.println(list);
Collections.fill(list, "我");
System.out.println(list);
}
}
//运行结果:[a, b, c, d, e, f]
// [我, 我, 我, 我, 我, 我]
5)copy(List m,List n)方法的使用(将集合n中的元素全部复制到m中,并且覆盖相应索引的元素)
public class TestCollection {
public static void main(String[] args) {
List<String> m = Arrays.asList("a b c d e f".split(" "));
List<String> n = Arrays.asList("我 我 我".split(" "));
Collections.copy(m, n);
System.out.println(m);
}
}
//运行结果:[我, 我, 我, d, e, f]
6)min/max(Collection),min/max(Collection,Comparator)方法的使用(前者采用Collection的自然比较法,后者采用Comparator进行比较)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
System.out.println(Collections.min(list));
}
}
//运行结果:a
7)indexOfSubList(List m,List m)方法的使用(查找n在m中首次出现位置的索引)
public class TestCollection {
public static void main(String[] args) {
List<String> m = Arrays.asList("a b b c b d e f".split(" "));
List<String> n = Arrays.asList("b");
System.out.println(Collections.indexOfSubList(m, n));
}
}
//运行结果:1
8)indexOfSubList(List m,List m)方法的使用(查找n在m中首次出现位置的索引)、lastIndexOfSubList(List m,List m)方法的使用(查找n在m中最后出现位置的索引)
public class TestCollection {
public static void main(String[] args) {
List<String> m = Arrays.asList("a b b c b d e f".split(" "));
List<String> n = Arrays.asList("b");
System.out.print(Collections.indexOfSubList(m, n));
System.out.println(Collections.lastIndexOfSubList(m, n));
}
}
//运行结果:1 4
9)rotate(List list,int m)方法的使用(集合中的元素向后移动m个位置,在后面被覆盖的元素循环到前面。m是负数表示向左移动,m是正数表示向右移动)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
Collections.rotate(list, 1);
System.out.println(list);
Collections.rotate(list, -1);
System.out.println(list);
}
}
//运行结果:[f, a, b, c, d, e]
// [a, b, c, d, e, f]
10)swap(List list,int i,int j)方法的使用(交换集合中指定元素索引未知的元素)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
Collections.swap(list, 2, 3);
System.out.println(list);
}
}
//运行结果:[a, b, d, c, e, f]
11)binarySearch(Collection,Object)方法的使用(查找指定集合中的元素,返回所查找元素位置的索引)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
int index = Collections.binarySearch(list, "d");
System.out.println(index);
}
}
//运行结果:3
12)replaceAll(List list,Object old,Object new)方法的使用(替换指定元素为新元素,若被替换的元素存在返回true,反之返回false)
public class TestCollection {
public static void main(String[] args) {
List<String> list = Arrays.asList("a b c d e f".split(" "));
System.out.println(Collections.replaceAll(list, "e", "我"));
System.out.println(Collections.replaceAll(list, "ee", "我"));
System.out.println(list);
}
}
//运行结果:true
// false
// [a, b, c, d, 我, f]
13其它示例:
/**
* 得到集合里按顺序存放的key之后的某一Key
*/
OrderedMap map = new LinkedMap();
map.put("FIVE", "5");
map.put("SIX", "6");
map.put("SEVEN", "7");
map.firstKey(); // returns "FIVE"
map.nextKey("FIVE"); // returns "SIX"
map.nextKey("SIX"); // returns "SEVEN"
/**
* 通过key得到value
* 通过value得到key
* 将map里的key和value对调
*/
BidiMap bidi = new TreeBidiMap();
bidi.put("SIX", "6");
bidi.get("SIX"); // returns "6"
bidi.getKey("6"); // returns "SIX"
// bidi.removeValue("6"); // removes the mapping
BidiMap inverse = bidi.inverseBidiMap(); // returns a map with keys and values swapped
System.out.println(inverse);
/**
* 得到两个集合中相同的元素
*/
List<String> list1 = new ArrayList<String>();
list1.add("1");
list1.add("2");
list1.add("3");
List<String> list2 = new ArrayList<String>();
list2.add("2");
list2.add("3");
list2.add("5");
Collection c = CollectionUtils.retainAll(list1, list2);
System.out.println(c);
14总结
reverse(List list):反转指定List集合中元素的顺序
shuffle(List list):对List中的元素进行随机排序(洗牌)
sort(List list):对List里的元素根据自然升序排序
sort(List list, Comparator c):自定义比较器进行排序
swap(List list, int i, int j):将指定List集合中i处元素和j出元素进行交换
rotate(List list, int distance):将所有元素向右移位指定长度
binarySearch(List list, Object key):使用二分搜索法,以获得指定对象在List中的索引,前提是集合已经排序
max(Collection coll):返回最大元素
max(Collection coll, Comparator comp):根据自定义比较器,返回最大元素
min(Collection coll):返回最小元素
min(Collection coll, Comparator comp):根据自定义比较器,返回最小元素
fill(List list, Object obj):使用指定对象填充
frequency(Collection Object o):返回指定集合中指定对象出现的次数
replaceAll(List list, Object old, Object new):替换
commons-io是一款处理io流的工具,封装了很多处理io流和文件的方法,可以大大简化我们处理io流和操作文件的代码。从common-io的官方使用文档可以看出,它主要分为工具类、尾端类、行迭代器、文件过滤器、文件比较器和扩展流。
官网地址:http://commons.apache.org/proper/commons-io/
下载 :http://commons.apache.org/proper/commons-io/download_io.cgi
工具类包括FileUtils、IOUtils、FilenameUtils和FileSystemUtils,前三者的方法并没有多大的区别,只是操作的对象不同,故名思议:FileUtils主要操作File类,IOUtils主要操作IO流,FilenameUtils则是操作文件名,FileSystemUtils包含了一些JDK没有提供的用于访问文件系统的实用方法。当前,只有一个用于读取硬盘空余空间的方法可用。实例如下
FileUtils的使用:
package com.wj.test;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class FileUtilsTest {
private String basePath = null;
@Before
public void setUp() {
basePath = System.getProperty("user.dir") + "\\file\\";
}
@After
public void tearDown() throws Exception {
}
/**
* 拷贝文件
* @throws IOException
*/
@Test
public void testCopy() throws IOException {
File srcFile = new File(basePath + "a.txt");
File destFile = new File(basePath + "b.txt");
FileUtils.copyFile(srcFile, destFile);
}
/**
* 删除文件
* @throws IOException
*/
@Test
public void testDelete() throws IOException{
File delFile = new File(basePath + "b.txt");
FileUtils.forceDelete(delFile);
//FileUtils.forceMkdir(delFile);
}
/**
* 比较文件内容
* @throws IOException
*/
@Test
public void testCompareFile() throws IOException{
File srcFile = new File(basePath + "a.txt");
File destFile = new File(basePath + "b.txt");
boolean result = FileUtils.contentEquals(srcFile, destFile);
System.out.println(result);
}
/**
* 移动文件
* @throws IOException
*/
@Test
public void testMoveFile() throws IOException{
File srcFile = new File(basePath + "b.txt");
File destDir = new File(basePath + "move");
FileUtils.moveToDirectory(srcFile, destDir, true);
}
/**
* 读取文件内容
* @throws IOException
*/
@Test
public void testRead() throws IOException{
File srcFile = new File(basePath + "a.txt");
String content = FileUtils.readFileToString(srcFile);
List<String> contents = FileUtils.readLines(srcFile);
System.out.println(content);
System.out.println("******************");
for (String string : contents) {
System.out.println(string);
}
}
/**
* 写入文件内容
* @throws IOException
*/
@Test
public void testWrite() throws IOException{
File srcFile = new File(basePath + "a.txt");
FileUtils.writeStringToFile(srcFile, "\nyes文件", true);
}
}
FileSystemUtils的使用:
package com.wj.test;
import java.io.IOException;
import org.apache.commons.io.FileSystemUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class FileSystemUtilsTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
/**
* 获取磁盘空余空间
* @throws IOException
*/
@SuppressWarnings("deprecation")
@Test
public void testFreeSpace() throws IOException {
// 以字节为单位
System.out.println(FileSystemUtils.freeSpace("c:\\") / 1024 / 1024 / 1024);
System.out.println(FileSystemUtils.freeSpace("d:\\") / 1024 / 1024 / 1024);
// 以k为单位
System.out.println(FileSystemUtils.freeSpaceKb("e:\\") / 1024 / 1024);
System.out.println(FileSystemUtils.freeSpaceKb("f:\\") / 1024 / 1024);
}
}
不同的计算机体系结构使用不同约定的字节排序。在所谓的“低位优先”体系结构中(如Intel),低位字节处于内存中最低位置,而其后的字节,则处于更高的位置。在“高位优先”的体系结构中(如Motorola),这种情况恰恰相反。
这个类库上有两个相关类:
EndianUtils包含用于交换java原对象和流之间的字节序列。
SwappedDataInputStream类是DataInput接口的一个实例。使用它,可以读取非本地的字节序列。
org.apache.commons.io.LineIterator类提供了一个灵活的方式与基于行的文件交互。可以直接创建一个实例,或者使用FileUtils或IOUtils的工厂方法来创建,实例如下:
package com.wj.test;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class LineIteratorTest {
private String basePath = null;
@Before
public void setUp() throws Exception {
basePath = System.getProperty("user.dir") + "\\file\\";
}
@After
public void tearDown() throws Exception {
}
/**
* 测试行迭代器
* @throws IOException
*/
@Test
public void testIterator() throws IOException{
File file = new File(basePath + "a.txt");
LineIterator li = FileUtils.lineIterator(file);
while(li.hasNext()){
System.out.println(li.nextLine());
}
LineIterator.closeQuietly(li);
}
}
org.apache.commons.io.filefilter包定义了一个合并了java.io.FileFilter以及java.io.FilenameFilter的接口(IOFileFilter)。除此之外,这个包还提供了一系列直接可用的IOFileFilter的实现类,可以通过他们合并其它的文件过滤器。比如,这些文件过滤器可以在列出文件时使用或者在使用文件对话框时使用。实例如下:
package com.wj.test;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.filefilter.EmptyFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class FileFilterTest {
private String basePath = null;
@Before
public void setUp() throws Exception {
basePath = System.getProperty("user.dir") + "\\file\\";
}
@After
public void tearDown() throws Exception {
}
/**
* 空内容文件过滤器
* @throws IOException
*/
@Test
public void testEmptyFileFilter() throws IOException{
File dir = new File(basePath);
String[] files = dir.list(EmptyFileFilter.NOT_EMPTY);
for (String file : files) {
System.out.println(file);
}
}
/**
* 文件名称后缀过滤器
* @throws IOException
*/
@Test
public void testSuffixFileFilter() throws IOException{
File dir = new File(basePath);
String[] files = dir.list(new SuffixFileFilter("a.txt"));
for (String file : files) {
System.out.println(file);
}
}
}
org.apache.commons.io.comparator包为java.io.File提供了一些java.util.Comparator接口的实现。例如,可以使用这些比较器对文件集合或数组进行排序。实例如下:
package com.wj.test;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.comparator.CompositeFileComparator;
import org.apache.commons.io.comparator.DirectoryFileComparator;
import org.apache.commons.io.comparator.NameFileComparator;
import org.apache.commons.io.comparator.PathFileComparator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ComparatorTest {
private String basePath = null;
@Before
public void setUp() throws Exception {
basePath = System.getProperty("user.dir") + "\\file\\";
}
@After
public void tearDown() throws Exception {
}
/**
* 文件名称比较器
* @throws IOException
*/
@Test
public void testNameFileComparator() throws IOException {
File f1 = new File(basePath + "a.txt");
File f2 = new File(basePath + "c.txt");
int result = NameFileComparator.NAME_COMPARATOR.compare(f1, f2);
System.out.println(result);
}
/**
* 文件路径比较器
* @throws IOException
*/
@Test
public void testPathFileComparator() throws IOException {
File f1 = new File(basePath + "a.txt");
File f2 = new File(basePath + "c.txt");
int result = PathFileComparator.PATH_COMPARATOR.compare(f1, f2);
System.out.println(result);
}
/**
* 组合比较器
* @throws IOException
*/
@SuppressWarnings("unchecked")
@Test
public void testCompositeFileComparator() throws IOException {
File dir = new File(basePath);
File [] files = dir.listFiles();
for (File file : files) {
System.out.println(file.getName());
}
CompositeFileComparator cfc = new CompositeFileComparator(
DirectoryFileComparator.DIRECTORY_COMPARATOR,
NameFileComparator.NAME_COMPARATOR);
cfc.sort(files);
System.out.println("*****after sort*****");
for (File file : files) {
System.out.println(file.getName());
}
}
}
org.apache.commons.io.input和org.apache.commons.io.output包中包含的针对数据流的各种各样的的实现。包括:
以上摘录自大佬文章https://blog.csdn.net/u011179993/article/details/46743521
InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
InputStreamReader inR = new InputStreamReader( in );
BufferedReader buf = new BufferedReader( inR );
String line;
while ( ( line = buf.readLine() ) != null ) {
System.out.println( line );
}
} finally {
in.close();
}
//使用IOUtils
InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
}
//2.读取文件
File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");
//3.察看剩余空间
long freeSpace = FileSystemUtils.freeSpace("C:/");
lang3是Apache Commons 团队发布的工具包,要求jdk版本在1.5以上,相对于lang来说完全支持java5的特性,废除了一些旧的API。该版本无法兼容旧有版本,于是为了避免冲突改名为lang3
lang包可以说是废弃了,以后请不要使用。采用lang3直接代替即可
org.apache.commons.lang3
org.apache.commons.lang3.builder
org.apache.commons.lang3.concurrent
org.apache.commons.lang3.event
org.apache.commons.lang3.exception
org.apache.commons.lang3.math
org.apache.commons.lang3.mutable
org.apache.commons.lang3.reflect
org.apache.commons.lang3.text
org.apache.commons.lang3.text.translate
org.apache.commons.lang3.time
org.apache.commons.lang3.tuple
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss");
Date date = new Date();
/**
* String转换成Date
* arg0 : 日期字符串 String
* arg1 : 特定的地理,政治和文化地区.可以传null
* arg3 : 日期格式.与arg0格式一致 String
* 该方法对日期和时间的解释是宽松的
* 宽松的解释日期(如 1996 年 2 月 42 日)将被视为等同于 1996 年 2 月 1 日后的第 41 天
* 如果是严格的解释,此类日期就会引发异常
*/
Date date1 = DateUtils.parseDate("20171012 14:30:12", Locale.TRADITIONAL_CHINESE, "yyyyMMdd hh:mm:ss");
Date date2 = DateUtils.parseDate("20171012 14:30:12", Locale.TRADITIONAL_CHINESE, "yyyyMMdd hh:mm:ss");
/**
* String转换成Date 严格的
* arg0 : 日期字符串 String
* arg1 : 特定的地理,政治和文化地区.可以传null
* arg3 : 日期格式.与arg0格式一致 String
* 该方法对日期和时间的解释是严格的
*/
Date date3 = DateUtils.parseDateStrictly("20171012", Locale.TRADITIONAL_CHINESE, "yyyyMMdd");
Date date4 = DateUtils.parseDateStrictly("20171012", Locale.TRADITIONAL_CHINESE, "yyyyMMdd");
/**
* 判断两个日期是否是同一天
* arg0 arg1 数据类型 : Date Calendar
* 比较arg0 arg1的
* ERA = 0 年代
* YEAR = 1 年
* DAY_OF_YEAR = 6 年中的第几天
*/
DateUtils.isSameDay(date3, date4);
System.out.println("isSameDay = " + DateUtils.isSameDay(date3, date4));
/**
* 判断两个日期是不是同一毫秒
* arg0 arg1 数据类型 : Date Calendar
* 自1970年1月1日00:00:00 GMT 的毫秒数是否相等
*/
DateUtils.isSameInstant(date1, date2);
System.out.println("isSameInstant = " + DateUtils.isSameInstant(date1, date2));
/**
* 判断是否是同一个本地时间
* arg0 arg1 数据类型 : Calendar
* 比较arg0 arg1的
* 数据类型
* ERA = 0 年代
* YEAR = 1 年
* DAY_OF_YEAR = 6 年中的第几天
* HOUR_OF_DAY = 11 天中的第几个小时
* MINUTE = 12 分钟
* SECOND = 13 秒
* MILLISECOND = 14 毫秒
*/
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
DateUtils.isSameLocalTime(cal1, cal2);
System.out.println("isSameLocalTime = " + DateUtils.isSameLocalTime(cal1, cal2));
/**
* 获取指定日期前后arg1年
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addYears(date1, 4);
System.out.println("addYears = " + sdf.format(date));
/**
* 获取指定日期前后arg1月
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addMonths(date1, 4);
System.out.println("addMonths = " + sdf.format(date));
/**
* 获取指定日期前后arg1周
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addWeeks(date1, 4);
System.out.println("addWeeks = " + sdf.format(date));
/**
* 获取指定日期前后arg1天
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addDays(date1, 4);
System.out.println("addDays = " + sdf.format(date));
/**
* 获取指定日期前后arg1小时
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addHours(date1, 4);
System.out.println("addHours = " + sdf.format(date));
/**
* 获取指定日期前后arg1分钟
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addMinutes(date1, 4);
System.out.println("addMinutes = " + sdf.format(date));
/**
* 获取指定日期前后arg1秒
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addSeconds(date1, 4);
System.out.println("addSeconds = " + sdf.format(date));
/**
* 获取指定日期前后arg1毫秒
* arg0 : 指定日期 Date类型
* arg1 : int型,正数向后天数,0当天,负数向前天数
*/
date = DateUtils.addMilliseconds(date1, 4);
System.out.println("addMilliseconds = " + sdf.format(date));
/**
* 指定日期年的值
* arg0 : 日期 Date类型
* arg1 : int型
*/
date = DateUtils.setYears(date1, 2008);
System.out.println("setYears = " + sdf.format(date));
/**
* 指定日期月的值
* arg0 : 日期 Date类型
* arg1 : int型 范围在 1-12
*/
date = DateUtils.setMonths(date1, 1);
System.out.println("setMonths = " + sdf.format(date));
/**
* 指定日期天的值
* arg0 : 日期 Date类型
* arg1 : int型 范围在 1-31(不同月份值略有不同)
*/
date = DateUtils.setDays(date1, 24);
System.out.println("setDays = " + sdf.format(date));
/**
* 指定日期小时的值
* arg0 : 日期 Date类型
* arg1 : int型 范围在1-23
*/
date = DateUtils.setHours(date1, 23);
System.out.println("setHours = " + sdf.format(date));
/**
* 指定日期分钟的值
* arg0 : 日期 Date类型
* arg1 : int型 范围在1-59
*/
date = DateUtils.setMinutes(date1, 56);
System.out.println("setMinutes = " + sdf.format(date));
/**
* 指定日期秒的值
* arg0 : 日期 Date类型
* arg1 : int型 范围在1-59
*/
date = DateUtils.setSeconds(date1, 14);
System.out.println("setMinutes = " + sdf.format(date));
/**
* 指定日期毫秒的值
* arg0 : 日期 Date类型
* arg1 : int型
*/
date = DateUtils.setMilliseconds(date1, 100);
System.out.println("setMinutes = " + sdf.format(date));
/**
* 相当于
* Calendar cal3 = Calendar.getInstance();
* cal3.setTime(date);
* 得到的cal
*/
Calendar cal3 = DateUtils.toCalendar(date1);
/**
* 获取时区
* timeZone 系统默认
* timeZone1 系统默认时区
* timeZone2 设置时区
*/
Calendar calendar = new GregorianCalendar();
TimeZone timeZone = calendar.getTimeZone();
TimeZone timeZone1 = TimeZone.getDefault();
TimeZone timeZone2 = TimeZone.getTimeZone("Europe/Copenhagen");
/**
* Date 转换成 Calendar 带时区
* arg0 : 日期 Date类型
* arg1 : 时区
*/
Calendar cal4 = DateUtils.toCalendar(date1, timeZone2);
long fragment = 0;
/**
* 获取指定日期中从指定位置起的毫秒数
* arg0 : 指定的日期 Date类型 或 Calendar类型
* arg1 : 指定从什么位置开始 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
fragment = DateUtils.getFragmentInMilliseconds(date1, Calendar.MONDAY);
System.out.println("getFragmentInMilliseconds = " + fragment);
/**
* 获取指定日期中从指定位置起的秒数
* arg0 : 指定的日期 Date类型 或 Calendar类型
* arg1 : 指定从什么位置开始 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
fragment = DateUtils.getFragmentInSeconds(date1, Calendar.MONDAY);
System.out.println("getFragmentInSeconds = " + fragment);
/**
* 获取指定日期中从指定位置起的分钟数
* arg0 : 指定的日期 Date类型 或 Calendar类型
* arg1 : 指定从什么位置开始 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
fragment = DateUtils.getFragmentInMinutes(date1, Calendar.MONDAY);
System.out.println("getFragmentInMinutes = " + fragment);
/**
* 获取指定日期中从指定位置起的小时数
* arg0 : 指定的日期 Date类型 或 Calendar类型
* arg1 : 指定从什么位置开始 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
fragment = DateUtils.getFragmentInHours(date1, Calendar.MONDAY);
System.out.println("getFragmentInHours = " + fragment);
/**
* 获取指定日期中从指定位置起的天数
* arg0 : 指定的日期 Date类型 或 Calendar类型
* arg1 : 指定从什么位置开始 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
fragment = DateUtils.getFragmentInDays(date1, Calendar.MONDAY);
System.out.println("getFragmentInDays = " + fragment);
boolean isEquals = false;
/**
* 判断两个时间在指定的位置之上是否相等
* arg0 : 时间1 Date类型 或 Calendar类型
* arg1 : 时间2 Date类型 或 Calendar类型
* arg2 : 指定在位置上开始比较 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
isEquals = DateUtils.truncatedEquals(date1, date2, Calendar.MONDAY);
System.out.println("truncatedEquals = " + isEquals);
int truncatedCompare = -1;
/**
* 比较arg0与arg1两个时间在指定的位置上的时间差值
* arg0 : 时间1 Date类型 或 Calendar类型
* arg1 : 时间2 Date类型 或 Calendar类型
* arg2 : 指定在位置上开始比较 int类型:建议使用 Calendar.YEAR Calendar.MONTH 等常量
*/
truncatedCompare = DateUtils.truncatedCompareTo(date1, date2, Calendar.MONDAY);
System.out.println("truncatedCompareTo = " + truncatedCompare);
用于对数组的操作,如添加、查找、删除、子数组、倒序、元素类型转换等
它提供了8中基本数据类型以及包装类以及各种类型的长度为0的空数组。所以以后需要长度为0的数组,可以不用new了,直接用这个即可
public static final int[] EMPTY_INT_ARRAY = new int[0];
public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
public static void main(String[] args) {
Integer[] inArr = new Integer[]{1, 2, 3};
Integer[] inArr2 = new Integer[]{1, 2, 3};
System.out.println(ArrayUtils.hashCode(inArr)); //862547
System.out.println(ArrayUtils.hashCode(inArr2)); //862547
inArr = new Integer[]{1, 2, 3};
inArr2 = new Integer[]{1, 3, 3};
System.out.println(ArrayUtils.hashCode(inArr)); //862547
System.out.println(ArrayUtils.hashCode(inArr2)); //862584
}
public static void main(String[] args) {
Integer[] inArr = new Integer[]{1, 2, 3};
Integer[] inArr2 = new Integer[]{1, 2, 3};
System.out.println(Objects.deepEquals(inArr, inArr2)); //true
inArr = new Integer[]{1, 2, 3};
inArr2 = new Integer[]{1, 3, 3};
System.out.println(Objects.deepEquals(inArr, inArr2)); //false
}
Integer[] integers = ArrayUtils.toArray(1, 2, 3);
Serializable[] serializables = ArrayUtils.toArray(1, 2, "3");
Integer[] inArr = new Integer[]{1, 2, 3};
int[] ints = ArrayUtils.toPrimitive(inArr);
Integer[] integers = ArrayUtils.toObject(ints);
public static void main(String[] args) {
Integer[] inArr = new Integer[]{1, 2, 3};
int[] ints = new int[]{1,2,3};
String[] strings = ArrayUtils.toStringArray(inArr);
//ArrayUtils.toStringArray(ints); //编译报错哟
}
需要注意:
public static void main(String[] args) {
Integer[] inArr = new Integer[]{1, 2, null};
//String[] strings = ArrayUtils.toStringArray(inArr);
//如果里面有null元素,会报错的,所以我们可以用下面这个方法 把null转成指定的值即可
String[] strings = ArrayUtils.toStringArray(inArr,"");
}
public static String rightPad(String str,int size,char padChar)
生成订单号,的时候还是很实用的。右边自动补齐。
StringUtils.rightPad(null, *, *) = null
StringUtils.rightPad("", 3, 'z') = "zzz"
StringUtils.rightPad("bat", 3, 'z') = "bat"
StringUtils.rightPad("bat", 5, 'z') = "batzz"
StringUtils.rightPad("bat", 1, 'z') = "bat"
StringUtils.rightPad("bat", -1, 'z') = "bat"
public static String leftPad(String str, int size,char padChar)
左边自动补齐
StringUtils.leftPad(null, *, *) = null
StringUtils.leftPad("", 3, 'z') = "zzz"
StringUtils.leftPad("bat", 3, 'z') = "bat"
StringUtils.leftPad("bat", 5, 'z') = "zzbat"
StringUtils.leftPad("bat", 1, 'z') = "bat"
StringUtils.leftPad("bat", -1, 'z') = "bat"
public static String center(String str,int size)
将字符在某特定长度下,句子
StringUtils.center(null, *) = null
StringUtils.center("", 4) = " "
StringUtils.center("ab", -1) = "ab"
StringUtils.center("ab", 4) = " ab "
StringUtils.center("abcd", 2) = "abcd"
StringUtils.center("a", 4) = " a "
public static String capitalize(String str)
首字母大写
StringUtils.capitalize(null) = null
StringUtils.capitalize("") = ""
StringUtils.capitalize("cat") = "Cat"
StringUtils.capitalize("cAt") = "CAt"
public static String swapCase(String str)
反向大小写
StringUtils.swapCase(null) = null
StringUtils.swapCase("") = ""
StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
public static String abbreviate(String str,
int maxWidth)
缩略字符串,省略号要占三位。maxWith小于3位会报错。
StringUtils.abbreviate(null, *) = null
StringUtils.abbreviate("", 4) = ""
StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
public static String abbreviate(String str,
int offset,
int maxWidth)
缩略字符串的一些高级用法
StringUtils.abbreviate(null, *, *) = null
StringUtils.abbreviate("", 0, 4) = ""
StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentException
StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentException
根据特定规则判断,不改变字符串自身
1)判断是否包含内容
注意:empty类和blank类,区别在对于前者只有为null或空串时,才返回true,而后者则会包含所有空白字符(空格、tab、换行、回车等)的判定,使用时需根据要实现的目的来选择具体用哪一个。
public static boolean isEmpty(CharSequence cs)
常用函数之一,判断字符串是否为""或者null
StringUtils.isEmpty(null) = true
StringUtils.isEmpty("") = true
StringUtils.isEmpty(" ") = false
StringUtils.isEmpty("bob") = false
public static boolean isNotEmpty(CharSequence cs)
最常用函数之一,跟上面方法相对
StringUtils.isNotEmpty(null) = false
StringUtils.isNotEmpty("") = false
StringUtils.isNotEmpty(" ") = true
StringUtils.isNotEmpty("bob") = true
public static boolean isAnyEmpty(CharSequence... css)
任意一个参数为空的话,返回true,如果这些参数都不为空的话返回false。
在写一些判断条件的时候,这个方法还是很实用的。
StringUtils.isAnyEmpty(null) = true
StringUtils.isAnyEmpty(null, "foo") = true
StringUtils.isAnyEmpty("", "bar") = true
StringUtils.isAnyEmpty("bob", "") = true
StringUtils.isAnyEmpty(" bob ", null) = true
StringUtils.isAnyEmpty(" ", "bar") = false
StringUtils.isAnyEmpty("foo", "bar") = false
public static boolean isNoneEmpty(CharSequence... css)
任意一个参数是空,返回false
所有参数都不为空,返回true
注意这些方法的用法
StringUtils.isNoneEmpty(null) = false
StringUtils.isNoneEmpty(null, "foo") = false
StringUtils.isNoneEmpty("", "bar") = false
StringUtils.isNoneEmpty("bob", "") = false
StringUtils.isNoneEmpty(" bob ", null) = false
StringUtils.isNoneEmpty(" ", "bar") = true
StringUtils.isNoneEmpty("foo", "bar") = true
public static boolean isBlank(CharSequence cs)
判断字符对象是不是空字符串,注意与isEmpty的区别
StringUtils.isBlank(null) = true
StringUtils.isBlank("") = true
StringUtils.isBlank(" ") = true
StringUtils.isBlank("bob") = false
public static boolean isNotBlank(CharSequence cs)
StringUtils.isNotBlank(null) = false
StringUtils.isNotBlank("") = false
StringUtils.isNotBlank(" ") = false
StringUtils.isNotBlank("bob") = true
原理同上
public static boolean isAnyBlank(CharSequence... css)
StringUtils.isAnyBlank(null) = true
StringUtils.isAnyBlank(null, "foo") = true
StringUtils.isAnyBlank(null, null) = true
StringUtils.isAnyBlank("", "bar") = true
StringUtils.isAnyBlank("bob", "") = true
StringUtils.isAnyBlank(" bob ", null) = true
StringUtils.isAnyBlank(" ", "bar") = true
StringUtils.isAnyBlank("foo", "bar") = false
public static boolean isNoneBlank(CharSequence... css)
StringUtils.isNoneBlank(null) = false
StringUtils.isNoneBlank(null, "foo") = false
StringUtils.isNoneBlank(null, null) = false
StringUtils.isNoneBlank("", "bar") = false
StringUtils.isNoneBlank("bob", "") = false
StringUtils.isNoneBlank(" bob ", null) = false
StringUtils.isNoneBlank(" ", "bar") = false
StringUtils.isNoneBlank("foo", "bar") = true
2) 比较字符串
基本用法equals、equalsIgnoreCase、compareTo、compareToIgnoreCase,同jdk.
扩展点:
public static boolean equals(CharSequence cs1,
CharSequence cs2)
字符串比对方法,是比较实用的方法之一,两个比较的字符串都能为空,不会报空指针异常。
StringUtils.equals(null, null) = true
StringUtils.equals(null, "abc") = false
StringUtils.equals("abc", null) = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false
public static boolean equalsIgnoreCase(CharSequence str1,
CharSequence str2)
上面方法的变体字符串比较(忽略大小写),在验证码……等字符串比较,真是很实用。
StringUtils.equalsIgnoreCase(null, null) = true
StringUtils.equalsIgnoreCase(null, "abc") = false
StringUtils.equalsIgnoreCase("abc", null) = false
StringUtils.equalsIgnoreCase("abc", "abc") = true
StringUtils.equalsIgnoreCase("abc", "ABC") = true
3) 包含字符串
public static boolean contains(CharSequence seq,
int searchChar)
字符串seq是否包含searchChar
StringUtils.contains(null, *) = false
StringUtils.contains("", *) = false
StringUtils.contains("abc", 'a') = true
StringUtils.contains("abc", 'z') = false
public static boolean containsAny(CharSequence cs,
char... searchChars)
包含后面数组中的任意对象,返回true
StringUtils.containsAny(null, *) = false
StringUtils.containsAny("", *) = false
StringUtils.containsAny(*, null) = false
StringUtils.containsAny(*, []) = false
StringUtils.containsAny("zzabyycdxx",['z','a']) = true
StringUtils.containsAny("zzabyycdxx",['b','y']) = true
StringUtils.containsAny("aba", ['z']) = false
4) 检验字符串
通过一系列实现好的方法,来快速返回是否符合特定规则
//判断是否只包含unicode字符(注意:汉字也是unicode字符)
public static boolean isAlpha(CharSequence cs)
//判断是否只包含unicode字符及空格
public static boolean isAlphaSpace(CharSequence cs)
//判断是否只包含unicode字符及数字
public static boolean isAlphanumeric(CharSequence cs)
//判断是否只包含unicode字符、数字及空格
public static boolean isAlphanumericSpace(CharSequence cs)
//判断是否只包含数字及空格
public static boolean isNumericSpace(CharSequence cs)
//判断是否只包含可打印的ascii码字符(注意,空格不属于范围内)
public static boolean isAsciiPrintable(CharSequence cs)
//判断是否为数字(注意:小数点和正负号,都会判定为false)
public static boolean isNumeric(CharSequence cs)
//判定是否只包括空白字符
public static boolean isWhitespace(CharSequence cs)
//判定是否全部为大写
public static boolean isAllUpperCase(CharSequence cs)
//判定是否全部为小写
public static boolean isAllLowerCase(CharSequence cs)
//判定是否混合大小写(注意:包含其他字符,如空格,不影响结果判定)
public static boolean isMixedCase(CharSequence cs)
示例
public static boolean isAlpha(CharSequence cs)
判断字符串是否由字母组成
StringUtils.isAlpha(null) = false
StringUtils.isAlpha("") = false
StringUtils.isAlpha(" ") = false
StringUtils.isAlpha("abc") = true
StringUtils.isAlpha("ab2c") = false
StringUtils.isAlpha("ab-c") = false
5) 起止字符判定
//startWith
public static boolean startsWith(CharSequence str,CharSequence prefix)
public static boolean startsWithIgnoreCase(CharSequence str,CharSequence prefix)
public static boolean startsWithAny(CharSequence sequence,CharSequence... searchStrings)
//endWith
public static boolean endsWith(CharSequence str,CharSequence suffix)
public static boolean endsWithIgnoreCase(CharSequence str,CharSequence suffix)
public static boolean endsWithAny(CharSequence sequence,CharSequence... searchStrings)
不改变字符串实质内容,对首尾以及中间的空白字符进行处理
1) 移除空白字符
去除首尾的空白字符,提供了两类方法,strip类和trim类,
trim类与jdk差异不大,去除包含控制字符(ascii码<=32)在内的控制字符(底层应用没做过,有可能会用到控制字符吧),主要是增加了对null的处理。
strip类则做了很多增强,通过重载方法实现了很多其他功能,建议在开发中使用strip类。
注意:全角空格并不在处理范围内。
签名:
public static String trim(String str)
移除字符串两端的空字符串,制表符char <= 32如:\n \t
如果为空的话,返回空
如果为""
StringUtils.trim(null) = null
StringUtils.trim("") = ""
StringUtils.trim(" ") = ""
StringUtils.trim("abc") = "abc"
StringUtils.trim(" abc ") = "abc"
变体有
public static String trimToNull(String str)
public static String trimToEmpty(String str)
不常用,跟trim()方法类似
public static String strip(String str)
public static String strip(String str,
String stripChars)
str:被处理的字符串,可为空
stripChars: 删除的字符串,
StringUtils.strip(null, *) = null
StringUtils.strip("", *) = ""
StringUtils.strip("abc", null) = "abc"
StringUtils.strip(" abc", null) = "abc"
StringUtils.strip("abc ", null) = "abc"
StringUtils.strip(" abc ", null) = "abc"
StringUtils.strip(" abcyx", "xyz") = " abc"
public static String deleteWhitespace(String str)
//对字符串基本处理的复合应用,将字符串中所有空白字符去除
删除空格
StringUtils.deleteWhitespace(null) = null
StringUtils.deleteWhitespace("") = ""
StringUtils.deleteWhitespace("abc") = "abc"
StringUtils.deleteWhitespace(" ab c ") = "abc"
public static String normalizeSpace(String str)
//去除声调音标,官方举例是将 ‘à’ 转换为’a’,很生僻,基本不会用到,不确定汉语拼音的音标是否能处理
public static String stripAccents(String input)
public static String removeStart(String str,
String remove)
//去除首尾,但中间的空白字符,替换为单个空格
删除以特定字符串开头的字符串,如果没有的话,就不删除。
StringUtils.removeStart(null, *) = null
StringUtils.removeStart("", *) = ""
StringUtils.removeStart(*, null) = *
StringUtils.removeStart("www.domain.com", "www.") = "domain.com"
StringUtils.removeStart("domain.com", "www.") = "domain.com"
StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
StringUtils.removeStart("abc", "") = "abc"
2) 去除换行
去除结尾的一处换行符,包括三种情况 \r \n \r\n
public static String chomp(String str)
示例
StringUtils.chomp("\r") = ""
StringUtils.chomp("\n") = ""
StringUtils.chomp("\r\n") = ""
StringUtils.chomp("abc \r") = "abc "
StringUtils.chomp("abc\n") = "abc"
StringUtils.chomp("abc\r\n") = "abc"
StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
StringUtils.chomp("abc\n\r") = "abc\n"
StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
3) 去除间隔符
去除末尾一个字符,常见使用场景是通过循环处理使用间隔符拼装的字符串,去除间隔符
注意:使用时需确保最后一位一定是间隔符,否则有可能破坏正常数据
public static String chop(String str)
示例:
StringUtils.chop("1,2,3,") = "1,2,3"
StringUtils.chop("a") = ""
StringUtils.chop("abc") = "ab"
StringUtils.chop("abc\nabc") = "abc\nab"
//此外,末尾的换行符也视为字符,如果结尾是\r\n,则一块去除,建议使用专用的chomp,以免造成非预期的结果
StringUtils.chop("\r") = ""
StringUtils.chop("\n") = ""
StringUtils.chop("\r\n") = ""
4) 去除非数字
去除所有非数字字符,将剩余的数字字符拼接成字符串
public static String getDigits(String str)
示例:
StringUtils.getDigits("abc") = ""
StringUtils.getDigits("1000$") = "1000"
StringUtils.getDigits("1123~45") = "112345"
StringUtils.getDigits("(541) 754-3010") = "5417543010"
public static int indexOf(CharSequence seq,
int searchChar)
indexOf这个方法不必多说,这个方法主要处理掉了空字符串的问题,不会报空指针,有一定用处
StringUtils.indexOf(null, *) = -1
StringUtils.indexOf("", *) = -1
StringUtils.indexOf("aabaabaa", 'a') = 0
StringUtils.indexOf("aabaabaa", 'b') = 2
public static int ordinalIndexOf(CharSequence str,
CharSequence searchStr,
int ordinal)
字符串在另外一个字符串里,出现第Ordinal次的位置
StringUtils.ordinalIndexOf(null, *, *) = -1
StringUtils.ordinalIndexOf(*, null, *) = -1
StringUtils.ordinalIndexOf("", "", *) = 0
StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
public static int lastIndexOf(CharSequence seq,
int searchChar)
字符串最后一次出现的位置
StringUtils.lastIndexOf(null, *) = -1
StringUtils.lastIndexOf("", *) = -1
StringUtils.lastIndexOf("aabaabaa", 'a') = 7
StringUtils.lastIndexOf("aabaabaa", 'b') = 5
public static int lastOrdinalIndexOf(CharSequence str,
CharSequence searchStr,
int ordinal)
字符串searchStr在str里面出现倒数第ordinal出现的位置
StringUtils.lastOrdinalIndexOf(null, *, *) = -1
StringUtils.lastOrdinalIndexOf(*, null, *) = -1
StringUtils.lastOrdinalIndexOf("", "", *) = 0
StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1) = 7
StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2) = 6
StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1) = 5
StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2) = 2
StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1) = 8
StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2) = 8
扩展
//增加忽略大小写控制
public static int indexOfIgnoreCase(CharSequence str,CharSequence searchStr)
//返回第n次匹配的所在的索引数。
public static int ordinalIndexOf(CharSequence str,CharSequence searchStr,int ordinal)
//同时查找多个字符
public static int indexOfAny(CharSequence cs,char... searchChars)
//返回不在搜索字符范围内的第一个索引位置
public static int indexOfAnyBut(CharSequence cs,char... searchChars)
字符串的分割、合并、截取、替换
1) 截取字符串
相关方法有多个,substring和truncate基本用法同jdk,内部处理异常
public static String substring(String str,int start)
public static String substring(String str,int start,int end)
public static String truncate(String str,int maxWidth);
public static String truncate(String str,int offset,int maxWidth)
扩展:
//直接实现从左侧、右侧或中间截取指定位数,实用性高
public static String left(String str,int len)
public static String right(String str,int len)
public static String mid(String str,int pos,int len)
//直接实现特定规则,但总体来说适用场景不多
//截取第一个指定字符前/后的字符串返回
public static String substringBefore(String str,String separator)
public static String substringAfter(String str,String separator)
//截取最后一个指定字符前/后的字符串返回
public static String substringBeforeLast(String str,String separator)
public static String substringAfterLast(String str,String separator)
//截取特定字符串中间部分
public static String substringBetween(String str,String tag)
示例:StringUtils.substringBetween("tagabctag", "tag") = "abc"
//返回起止字符串中间的字符串,且只返回第一次匹配结果
public static String substringBetween(String str,String open,String close)
//返回起止字符串中间的字符串,返回所有匹配结果
public static String[] substringBetween(String str,String open,String close)
public static String substring(String str,
int start)
字符串截取
StringUtils.substring(null, *) = null
StringUtils.substring("", *) = ""
StringUtils.substring("abc", 0) = "abc"
StringUtils.substring("abc", 2) = "c"
StringUtils.substring("abc", 4) = ""
StringUtils.substring("abc", -2) = "bc"
StringUtils.substring("abc", -4) = "abc"
public static String left(String str,
int len)
public static String right(String str,
int len)
public static String mid(String str,
int pos,
int len)
2) 分割字符串
jdk中的split使用正则表达式匹配,而字符串分割最常用场景是如下这种根据间隔符分割
String str="he,ll,o";
String [] reuslt=str.split(",");
虽然split的方式也能实现效果,但是还有有点别扭,而在StringUtils,就是通过字符串匹配,而不是正则表达式
//不设置间隔符,默认使用空白字符分割
public static String[] split(String str)
public static String[] split(String str,
String separatorChars)
//根据间隔符分割
public static String[] splitByWholeSeparator(String str,String separator)
//限定返回,贪婪匹配
public static String[] splitByWholeSeparator(String str,String separator,int max),
示例:
StringUtils.split(null, *) = null
StringUtils.split("", *) = []
StringUtils.split("abc def", null) = ["abc", "def"]
StringUtils.split("abc def", " ") = ["abc", "def"]
StringUtils.split("abc def", " ") = ["abc", "def"]
StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
//空白字符作为一个数组元素返回(其他方法默认去除空白字符元素)
public static String[] splitPreserveAllTokens(String str)
示例:
StringUtils.splitPreserveAllTokens("abc def") = ["abc", "def"]
StringUtils.splitPreserveAllTokens("abc def") = ["abc", "", "def"]
StringUtils.splitPreserveAllTokens(" abc ") = ["", "abc", ""]
//特定场景,根据字符类型分割,同一类划为一个数组元素,驼峰命名情况下,最后一个大写字母归属后面元素而不是前面
public static String[] splitByCharacterTypeCamelCase(String str)
示例:
StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
StringUtils.splitByCharacterTypeCamelCase("number5") = ["number", "5"]
StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]
3) 合并字符串
jdk使用concat方法,StringUtils使用join,这是一个泛型方法,建议实际使用过程中,还是只对String使用,不要对数值类型进行合并,会导致代码可读性降低
//默认合并,注意:自动去除空白字符或null元素
public static <T> String join(T... elements)
字符串连接
StringUtils.join(null) = null
StringUtils.join([]) = ""
StringUtils.join([null]) = ""
StringUtils.join(["a", "b", "c"]) = "abc"
StringUtils.join([null, "", "a"]) = "a"
public static String join(Object[] array,
char separator)
特定字符串连接数组,很多情况下还是蛮实用,不用自己取拼字符串
StringUtils.join(null, *) = null
StringUtils.join([], *) = ""
StringUtils.join([null], *) = ""
StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
StringUtils.join(["a", "b", "c"], null) = "abc"
StringUtils.join([null, "", "a"], ';') = ";;a"
4) 翻转
public static String reverse(String str)
字符串翻转
StringUtils.reverse(null) = null
StringUtils.reverse("") = ""
StringUtils.reverse("bat") = "tab"
5) 其它
public static String defaultString(String str, String defaultStr)
默认字符串,相当于三目运算,前面弱为空,则返回后面一个参数
StringUtils.defaultString(null, "NULL") = "NULL"
StringUtils.defaultString("", "NULL") = ""
StringUtils.defaultString("bat", "NULL") = "bat"
toFullyQualifiedName(Class context, String resourceName) 返回一个由class包名+resourceName拼接的字符串
public static void main(String[] args) {
String fullPath = ClassPathUtils.toFullyQualifiedName(Integer.class, "");
System.out.println(fullPath); //java.lang.
//fullPath = ClassPathUtils.toFullyQualifiedName(Integer.class.getPackage(), "Integer.value");
fullPath = ClassPathUtils.toFullyQualifiedName(Integer.class, "Integer.value");
System.out.println(fullPath); //java.lang.Integer.value
}
ClassPathUtils.toFullyQualifiedPath(StringUtils.class
, "StringUtils.properties") = "org/apache/commons/lang3/StringUtils.properties"
1) getShortClassName:
public static void main(String[] args) {
System.out.println(int[].class.getSimpleName()); //int[]
System.out.println(ClassUtils.getShortClassName(int[].class)); //int[]
System.out.println(ClassUtils.getShortClassName(String.class)); //String
System.out.println(ClassUtils.getShortClassName(ArrayList.class)); //ArrayList
System.out.println(ClassUtils.getShortClassName("List")); //List
}
2) getPackageName:获取包名
public static void main(String[] args) {
System.out.println(ClassUtils.getPackageName(int[].class)); //""
System.out.println(ClassUtils.getPackageName(String.class)); //java.lang
}
3) getAllSuperclasses:获取到该类的所有父类 注意:只是父类 不包含接口
public static void main(String[] args) {
List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(ArrayList.class);
System.out.println(ArrayUtils.toString(allSuperclasses)); //[class java.util.AbstractList, class java.util.AbstractCollection, class java.lang.Object]
}
public static void main(String[] args) {
List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(ArrayList.class);
System.out.println(ArrayUtils.toString(allSuperclasses)); //[class java.util.AbstractList, class java.util.AbstractCollection, class java.lang.Object]
allSuperclasses = ClassUtils.getAllSuperclasses(Object.class);
System.out.println(ArrayUtils.toString(allSuperclasses)); //[]
}
getAllInterfaces:同上。但此方法指的是接口
4) convertClassNamesToClasses/convertClassesToClassNames 见名知意
public static void main(String[] args) {
List<Class<?>> classes = ClassUtils.convertClassNamesToClasses(Arrays.asList("java.lang.Integer","java.lang.int"));
System.out.println(classes); //[class java.lang.Integer, null]
}
5) isPrimitiveOrWrapper、isPrimitiveWrapper 、primitiveToWrapper、primitivesToWrappers、wrapperToPrimitive判断是基本类型还是包装类型
public static void main(String[] args) {
System.out.println(ClassUtils.isPrimitiveOrWrapper(Integer.class)); //true
System.out.println(ClassUtils.isPrimitiveOrWrapper(int.class)); //true
//检测是否是包装类型
System.out.println(ClassUtils.isPrimitiveWrapper(Object.class)); //false 注意 此处是false
System.out.println(ClassUtils.isPrimitiveWrapper(Integer.class)); //true
System.out.println(ClassUtils.isPrimitiveWrapper(int.class)); //false
//检测是否是基本类型
System.out.println(Object.class.isPrimitive()); //false 注意 此处也是false
System.out.println(Integer.class.isPrimitive()); //false
System.out.println(int.class.isPrimitive()); //true
}
6) isAssignable:是否是相同的class类型 支持class、数组等等 挺实用的
7) isInnerClass:检查一个类是否是内部类或者静态内部类等
8) getClass:加强版的Class.forName() 可以指定值是否要马上初始化该类
9) hierarchy:获取到该类的继承结构
public static void main(String[] args) {
Iterable<Class<?>> hierarchy = ClassUtils.hierarchy(ArrayList.class);
hierarchy.forEach(System.out::println);
//输出了类的层级结构(默认是不包含接口的)
//class java.util.ArrayList
//class java.util.AbstractList
//class java.util.AbstractCollection
//class java.lang.Object
hierarchy = ClassUtils.hierarchy(ArrayList.class,ClassUtils.Interfaces.INCLUDE);
hierarchy.forEach(System.out::println);
//class java.util.ArrayList
//interface java.util.List
//interface java.util.Collection
//interface java.lang.Iterable
//interface java.util.RandomAccess
//interface java.lang.Cloneable
//interface java.io.Serializable
//class java.util.AbstractList
//class java.util.AbstractCollection
//class java.lang.Object
}
10) RandomStringUtils : 需要随机字符串的时候,它或许能帮上忙
public static void main(String[] args) {
//随便随机一个字 所以有可能是乱码
String random = RandomStringUtils.random(10);
//在指定范围内随机
String randomChars = RandomStringUtils.random(3,'a','b','c','d','e');
//随便随机10个Ascii
String randomAscii = RandomStringUtils.randomAscii(10);
//注意这里不是5到10内随机,而是随机一个长度的数字
String randomNumeric = RandomStringUtils.randomNumeric(5,10);
System.out.println(random); //?ᣒ?⍝?䆃ぬ
System.out.println(randomChars); //dac
System.out.println(randomAscii); //hpCQrtmUvi
System.out.println(randomNumeric); //2580338
}
在Json流行的时代,这个工具使用的几率就较小了。
//枚举类
public enum ImagesTypeEnum {
JPG,JPEG,PNG,GIF;
}
//测试
ImagesTypeEnum imagesTypeEnum = EnumUtils.getEnum(ImagesTypeEnum.class, "JPG");
System.out.println("imagesTypeEnum = " + imagesTypeEnum);
System.out.println("--------------");
List<ImagesTypeEnum> imagesTypeEnumList = EnumUtils.getEnumList(ImagesTypeEnum.class);
imagesTypeEnumList.stream().forEach(
imagesTypeEnum1 -> System.out.println("imagesTypeEnum1 = " + imagesTypeEnum1)
);
System.out.println("--------------");
Map<String, ImagesTypeEnum> imagesTypeEnumMap = EnumUtils.getEnumMap(ImagesTypeEnum.class);
imagesTypeEnumMap.forEach((k, v) -> System.out.println("key:" + k + ",value:" + v));
System.out.println("-------------");
boolean result = EnumUtils.isValidEnum(ImagesTypeEnum.class, "JPG");
System.out.println("result = " + result);
boolean result1 = EnumUtils.isValidEnum(ImagesTypeEnum.class, null);
System.out.println("result1 = " + result1);
输出:
imagesTypeEnum = JPG
--------------
imagesTypeEnum1 = JPG
imagesTypeEnum1 = JPEG
imagesTypeEnum1 = PNG
imagesTypeEnum1 = GIF
--------------
key:JPG,value:JPG
key:JPEG,value:JPEG
key:PNG,value:PNG
key:GIF,value:GIF
-------------
result = true
result1 = false
详解:一篇让你熟练掌握Google Guava包(全网最全)-------->>>>>直达链接
这个工具包其实也蛮实用的,对于我来说也挺不可替代的,经常涉及到的excel导入导出都只会用这个。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
具体的用法以前写过记录,这里直接放传送门:
java实现导入导出Excel文件
java使用poi导出实现单元格合并
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
这个其实是真的简单方便,我之前也有过教程,因为功能比较简单,所以也不存在不容易学,不好理解的情况,直接贴笔记:
大神文章—java-Kaptcha生成验证码图片(五分钟学会)
相信我,这个名字一点都不夸张,看一遍就能做出来,五分钟还是富裕的。然后这个真的挺方便的,在不知道它之前我写验证码这块都是自己生成图片,虽说能做,但是也复杂的多。整体而言值得一用。
项目中经验要用到socket的,其实java中socket的选择也不少,nettysocket,我记得之前还用过一个socket client的那个。这里只说我现在整理的项目中用到的netty-scoket.
使用笔记在这里:大神文章—spring boot 整合netty-socketio
https://cloud.tencent.com/developer/article/1497811
https://www.cnblogs.com/54chensongxia/p/11688868.html#apache-commons%E7%B1%BB%E5%BA%93
https://www.cnblogs.com/forfreewill/articles/13993629.html
https://blog.csdn.net/u011179993/article/details/46743521