Apache Commons Lang使用总结

StringUtils

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.util.Locale;

import static org.apache.commons.lang3.StringUtils.*;

/**
 * StringUtilsDemo
 * <p>
 * 空白字符
 * 空格 \s
 * 回车 \n
 * 换行 \r
 * 制表 \t
 * <p>
 *
 * @author Feathers
 * @date 2018-05-18 14:15
 */
public class StringUtilsDemo {

    public static final String NULL = "Null";
    public static final String EMPTY = "Empty";

    public static final String STR_NULL = null;
    public static final String STR_EMPTY = "";
    public static final String STR_BLANK = "  ";

    @Test
    public void testConstant() {
        String cr = StringUtils.CR; // \r
        String lf = StringUtils.LF; // \n
        String space = StringUtils.SPACE; // " "
        String empty = StringUtils.EMPTY; // ""
    }

    @Test
    public void testLength() {
        Log.i(length(null));
    }

    /**
     * 字符串数据类型判断
     */
    @Test
    public void testIs() {

        Log.i("判断字符串是否为Empty", isEmpty(""));
        Log.i("判断字符串是否为Blank", isBlank("\n\t "));
        Log.i("判断字符是否不是Empty", isNoneEmpty(""));
        Log.i("判断字符是否不是Blank", isNoneBlank(" "));

        Log.i("判断字符串内容是否为数字 123", isNumeric("123"));
        Log.i("判断字符串内容是否为数字 123 ", isNumeric("123 "));
        Log.i("判断字符串内容是否为数字 123.4", isNumeric("123.4"));
        Log.i("判断字符串内容是否为数字 12 3", isNumeric("12 3"));

        Log.i("判断字符串是否为纯Unicode字符组成", isAlpha("啊打发"));
        Log.i("判断字符串是否为纯Unicode字符组成 2,\\n, \\s等字符都属于ASCII", isAlpha("啊打发2"));
        Log.i("判断字符串是否为纯Unicode字符组成 空字符串/null会返回false", isAlpha(""));
        Log.i("判断字符串是否为纯Unicode字符以及空格组成", isAlphaSpace("沙发上 "));
        Log.i("判断字符串是否为纯Unicode字符以及数字组成", isAlphanumeric("沙发上123"));
        Log.i("判断字符串是否为纯Unicode字符以及数字和空格组成", isAlphanumericSpace("沙发上 123"));

        Log.i("判断字符串是否全为小写字母", isAllLowerCase("ad"));
        Log.i("判断字符串是否全为小写字母,只允许出现小写字母,如果有其他字符,比如汉字、数字,会返回false", isAllLowerCase("ads123"));
        Log.i("判断字符串是否全为大写字母", isAllUpperCase("AD"));
        Log.i("判断字符串时大小写混合", isMixedCase("ADa"));
        Log.i("判断字符串时大小写混合 可以包含其他中文、数字字符", isMixedCase("ADa 哈"));

    }

    /**
     * trim 操作只会去除字符串两侧的空白字符
     * 去空格操作 trim   if null then null
     * 去空格操作 trimToEmpty if null/"" then ""
     */
    @Test
    public void testTrim() {
        Log.i("---------trim------");
        Log.i("a_b", trim("a b"));
        Log.i(NULL, trim(STR_NULL));

        Log.i("--------trimToNull------");
        Log.i(NULL, trimToNull(STR_NULL));
        Log.i(EMPTY, trimToNull(STR_EMPTY));

        Log.i("--------trimToEmpty------");
        Log.i(NULL, trimToEmpty(STR_NULL).length());
        Log.i(EMPTY, trimToEmpty(STR_EMPTY).length());
    }

    /**
     * 移除字符串文本末尾出的\n,\r,\n\r 即回车符
     */
    @Test
    public void testChomp() {
        Log.i(chomp("a\n\r"));
    }

    /**
     * 去除指定的字符,如果不传,则默认去除空白字符
     * strip 去除两侧占位符
     * stripStart 去除字符串开始的指定字符
     * stripEnd 去除字符串结束的指定字符
     * stripAll 批量处理
     * stripAccents 去除字符串中的变音符号 #,b,x,bb,ヰ
     */
    @Test
    public void testStrip() {
        Log.i("---------strip-----------");
        String target = " a b ";
        Log.i("去除两侧的空白字符\t\t", strip(target));
        Log.i("去除两侧的指定字符\t\t", strip(target, "\\s"));
        Log.i("去除开始的的指定字符\t", stripStart(target, "\\s"));
        Log.i("去除字符串结束的指定字符\t", stripEnd(target, "\\s"));

        Log.i("---------stripToEmpty-----------");
        // 将空白字符进行strip操作,如果得到""或null 则返回 ""
        Log.i(EMPTY, stripToEmpty(STR_BLANK));

        Log.i("---------stripToNull-----------");
        // 将空白字符进行strip操作,如果得到""或null 则返回 null
        Log.i(NULL, stripToNull(STR_BLANK));

        Log.i("---------stripAll-----------");
        String[] strings1 = stripAll(" \n", " \t");
        Log.i("StripAll 去除空白字符", strings1);
        String[] strings2 = stripAll(new String[]{"ab", "acb", "adb"}, "b");
        Log.i("StripAll 去除指定字符", strings2);

        Log.i("----------stripAccents---------");
        Log.i(stripAccents("éclair"));

    }

    /**
     * 给字符串设置默认值
     * defaultString 如果字符串是 null 则设置默认字符串,默认字符串默认为""空字符串
     * defaultIfEmpty 如果字符串是空字符串,则设置默认字符串
     * defaultIfBlank 如果字符串是blank字符串,则设置默认字符串
     */
    @Test
    public void testDefault() {
        String defaultText = "我是默认文字";

        Log.i("defaultString", defaultString(null));
        Log.i("defaultString2", defaultString(null, defaultText));

        Log.i("defaultIfEmpty", defaultIfEmpty("", defaultText));
        Log.i("defaultIfBlank", defaultIfEmpty("   ", defaultText));
    }

    /**
     * 字符串比较
     */
    @Test
    public void testEquals() {
        Log.i("null eq null", StringUtils.equals(null, null));
        Log.i("忽略大小写比较", equalsIgnoreCase("a", "A"));
        Log.i("多个字符串与同一字符串比较", equalsAny("abc", "abd", "abc"));
        Log.i("多个字符串与同一字符串忽略大小写比较", equalsAnyIgnoreCase("abc", "abd", "ABC"));
    }

    /**
     * 字符串比较(大小比较,字典顺序)
     * 当前字符串1的字典顺序高于字符串2是,返回-1 否则返回 1
     */
    @Test
    public void testCompare() {
        Log.i("字符串比较", compare("abc", "abc"));
        Log.i("字符串比较", compare("abc", "abd"));
        Log.i("字符串比较", compare("abc", "abcd"));
        Log.i("字符串比较", compare("abd", "abc"));

        Log.i("字符串比较 忽略大小写", compareIgnoreCase("Abd", "abc"));
    }

    /**
     * 字符串查找
     */
    @Test
    public void testIndexOf() {

        Log.i("-------------indexOf-------------");
        Log.i("查找字符串a在字符串b中的位置", indexOf("abc", "a"));
        Log.i("如果没有查找到,返回-1", indexOf("abc", "d"));
        Log.i("如果两个字符串其中有一个未null,则返回-1", indexOf("abc", null));

        Log.i("指定位置开始查找", indexOf("abc", "b", 1));
        Log.i("查找字符", indexOf("abc", 'a'));

        Log.i("-------------indexOfIgnoreCase-------------");
        Log.i("忽略大小写查找", indexOfIgnoreCase("abc", "Ab"));

        Log.i("--------------ordinalIndexOf------------");
        Log.i("查找字符串在目标字符串中出现第ordinal次时的位置", ordinalIndexOf("abcb", "b", 2));

        Log.i("--------------indexOfDifference------------");
        Log.i("查找两个字符串开始不同的位置", indexOfDifference("abcd", "abde"));

        Log.i("---------------indexOfAny-------------------");
        Log.i("查找多个字符在目标字符串的位置", indexOfAny("abc", "a", "b"));

        Log.i("---------------indexOfAnyBut-------------------");
        Log.i("查找字符串不在目标字符串的位置", indexOfAnyBut("abc", "ab"));

        Log.i("--------------lastIndexOf-------------");
        Log.i("从后往前查找", lastIndexOf("abca", "a"));
        Log.i("从后往前忽略大小写查找", lastIndexOfIgnoreCase("abca", "A"));

    }

    /**
     * 字符串包含检查操作 contains
     */
    @Test
    public void testContains() {
        Log.i("检查字符串中是否有某个字符", contains("\na", 'a'));
        Log.i("检查字符串中是否有某个字符串", contains("\na", "a"));

        Log.i("检查字符串中是否有某些字符", containsAny("aa", 'a', 'c'));
        Log.i("检查字符串中是否有某些字符串", containsAny("aa", "c", "d"));

        Log.i("检查字符串中是否有空白字符", containsWhitespace(""));
        Log.i("检查字符串中是否有空白字符", containsWhitespace("\na"));

        Log.i("忽略大小写检查", contains("\na", "A"));

        Log.i("检查字符串中是否只包含某个字符", containsOnly("aaa", 'a'));
        Log.i("检查字符串中是否只包含某个字符串", containsOnly("aaac", "a"));

        Log.i("检查字符串中是否不包含参数二的字符", containsNone("aaac", 'd'));
        Log.i("检查字符串中是否不包含参数二的字符串", containsNone("aaac", "c"));

    }

    /**
     * 字符串开始结尾字符判断
     */
    @Test
    public void testStartEnd() {
        Log.i("判断字符串是否以某一字符串开始", startsWith("123_test", "123"));
        Log.i("判断字符串是否以任意列表中的字符串结束", startsWithAny("123_test", "123", "124"));
        Log.i("忽略大小写判断", startsWithIgnoreCase("123A_test", "123a"));

        Log.i("判断字符串是否以某一字符串结束", endsWith("123_test", "test"));
        Log.i("判断字符串是否以任意列表字符串字符串结束", endsWithAny("123_test", "test", "ha"));
        Log.i("忽略大小写判断", endsWithIgnoreCase("123_test", "Test"));
    }

    /**
     * 字符串截取
     */
    @Test
    public void testSubstring() {
        Log.i("截取[start, ends)的字符串", substring("abcd", 2, 3));
        Log.i("从指定位置截取字符", substring("abcd", 2));
        Log.i("从指定字符串位置开始截取该字符前面的字符串(从左向右查找该字符串)", substringBefore("abcd", "b"));
        Log.i("从指定字符串位置开始截取该字符前面的字符串(从右向左查找该字符串)", substringBeforeLast("abcd", "b"));

        Log.i("从指定字符串位置开始截取该字符后面的字符串(从左向右查找该字符串)", substringAfter("abcd", "b"));
        Log.i("从指定字符串位置开始截取该字符后面的字符串(从右向左查找该字符串)", substringAfterLast("abcd", "b"));

        Log.i("找到两个tag字符之间的字符并截取", substringBetween("abcda", "a"));
        Log.i("从指定指定start字符串的位置截取end字符的位置的字符串", substringBetween("abcd", "a", "d"));
        Log.i("从指定指定start字符串的位置截取end字符的位置的字符串, 将符合情况的全部输出", substringsBetween("abcdabecd", "a", "d"));

        Log.i("-------------left, right, mid----------------");
        Log.i("从左开始截取长度为len的字符串", left("abcd", 2));
        Log.i("从右开始截取长度为len的字符串", right("abcd", 2));
        Log.i("从pos位置开始截取,截取len长度的字符串", mid("abcd", 2, 2));
    }

    /**
     * 字符串截取
     */
    @Test
    public void testTruncate() {
        Log.i("从0开始截取五个字符作为一个字符串",StringUtils.truncate("abcdefghijk", 5));
        Log.i("从1开始截取五个字符作为一个字符串",StringUtils.truncate("abcdefghijk", 1,5));
    }

    /**
     * 字符串分割
     */
    @Test
    public void testSplit() {
        Log.i("使用空格将字符串分割为数组", split("a b c "));
        Log.i("使用指定字符串将字符串分割为数组", split("a,b,c,", ","));
        Log.i("使用指定字符串将字符串分割为数组", split("a,b,c,,", ","));

        Log.i("whole使用指定字符串将字符串分割为数组", splitByWholeSeparator("a,b,c,", ","));
        Log.i("whole使用指定字符串将字符串分割为数组,默认同样使用空格", splitByWholeSeparator("a b c", null));
        Log.i("whole使用指定字符串将字符串分割为数组,空字符串不会被忽略", splitByWholeSeparator("a,b,c,,", ","));
        Log.i("whole使用指定字符串将字符串分割为数组,设置数组最大长度", splitByWholeSeparator("a,b,c", ",", 2));
        Log.i("whole使用指定字符串将字符串分割为数组,设置数组最大长度 元素1为", splitByWholeSeparator("a,b,c", ",", 2)[1]);

        Log.i("按照字符串数据的不同类型进行分割", splitByCharacterType("abcABC!!!123a"));
        Log.i("按照字符串数据的不同类型进行分割,并且忽略大小写", splitByCharacterTypeCamelCase("abcABC!!!123a"));

        Log.i("splitPreserveAllTokens和whole作用相同,不忽略空白项", splitPreserveAllTokens("a b c "));
    }

    /**
     * 字符串拼接
     */
    @Test
    public void testJoin() {
        String[] as = new String[]{"a", "b", "c"};

        Log.i("将数组拼接为字符串,默认以空字符串为连接符", join(as));
        Log.i("将数组拼接为字符串,使用指定连接符", join(as, ","));
        Log.i("将数组指定位置的元素使用指定连接符拼接为字符串", join(as, ",", 2, 3));
    }

    /**
     * 字符串字符移除操作
     */
    @Test
    public void testRemove() {

        Log.i("移除字符串中的某个字符串(移除所有匹配)", remove("abcabc", "a"));
        Log.i("移除字符串中的某个字符串(移除匹配正则的所有字符串,和remove类似)", removePattern("abcabc", "a"));
        Log.i("移除字符串中的某个字符串(移除从左到右第一个匹配)", removeFirst("abcabc", "b"));

        Log.i("移除字符串中的某个字符串(如果头部有该字符串,则移除)", removeStart("abcabc", "a"));
        Log.i("移除字符串中的某个字符串(如果头部有该字符串,则移除,忽略大小写)", removeStartIgnoreCase("abcabc", "A"));
        Log.i("移除字符串中的某个字符串(如果尾部有该字符串,则移除)", removeEnd("abcabc", "c"));
        Log.i("移除字符串中的某个字符串(如果尾部有该字符串,则移除,忽略大小写)", removeEndIgnoreCase("abcabc", "c"));
    }

    /**
     * 删除方法
     */
    @Test
    public void testDelete() {
        Log.i("删除所有空白符", deleteWhitespace("a b \nd"));
    }

    /**
     * 字符串替换
     */
    @Test
    public void testReplace() {
        Log.i("替换字符串(所有匹配的都会被替换)", replace("abcabc", "a", "e"));
        Log.i("替换字符串(所有匹配的都会被替换)", replaceChars("abcabc", "a", "e"));
        Log.i("替换字符串(所有匹配的都会被替换)", replaceChars("abcabc", 'a', 'e'));
        Log.i("替换字符串(所有匹配的都会被替换, 但是最多替换max次)", replace("abcabc", "a", "e", 1));

        Log.i("替换字符串(忽略大小写)", replaceIgnoreCase("abcabc", "A", "e"));
        Log.i("替换字符串(忽略大小写,最多被替换max次)", replaceIgnoreCase("abcabc", "A", "e", 1));

        Log.i("替换字符串(只替换第一个匹配的)", replaceFirst("abcabc", "a", "e"));
        Log.i("替换字符串(只替换一次)", replaceOnce("abcabc", "a", "e"));

        Log.i("替换字符串,使用指定的正则表达式", replacePattern("abcabc", "a", "e"));

        Log.i("增强替换,只替换一次,如果两个参数数组长度不一致,会抛出非法参数异常",
                replaceEach("bcacab", new String[]{"a", "b", "c"}, new String[]{"d", "e", "f"}));
        Log.i("增强替换,替换多次,比如将a替换为b,b再替换为c,c替换为d,结果为dddddd",
                replaceEachRepeatedly("bcacab", new String[]{"a", "b", "c"}, new String[]{"b", "c", "d"}));
    }

    /**
     * 字符串覆盖
     * 如果start和end索引最小值大于当前字符串的长度,则默认覆盖字符串当前长度的位置
     * 如果start和end索引最大值小于当前字符串的长度,则默认插入到字符串的0位置
     */
    @Test
    public void testOverlay() {
        Log.i("将字符串的[start,end)位置使用ovrlay字符串覆盖", StringUtils.overlay("abcdef", "zz", 2, 4));
        Log.i("将字符串的[start,end)位置使用ovrlay字符串覆盖", StringUtils.overlay("abcdef", "zz", 4, 2));
        Log.i("特殊情况1", StringUtils.overlay("abcdef", "zz", -100, 2));
        Log.i("特殊情况2", StringUtils.overlay("abcdef", "zz", -100, -200));
        Log.i("特殊情况3", StringUtils.overlay("abcdef", "zz", 2, 100));
        Log.i("特殊情况4", StringUtils.overlay("abcdef", "zz", 50, 100));
    }

    /**
     * 填充
     */
    @Test
    public void testPad() {
        Log.i("----------左填充----------");
        Log.i("左填充,默认使用空格", leftPad("abc", 5));
        Log.i("左填充,长度满足不进行填充", leftPad("abc", 2));
        Log.i("左填充,指定填充字符", leftPad("abc", 5, "-"));

        Log.i("----------右填充----------");
        Log.i("右填充,默认使用空格", rightPad("abc", 5));
        Log.i("右填充,长度满足不进行填充", rightPad("abc", 2));
        Log.i("右填充,指定填充字符", rightPad("abc", 5, "-"));
    }

    /**
     * 居中
     */
    @Test
    public void testCenter() {
        Log.i("字符串居中,默认使用空格", center("abc", 5));
        Log.i("字符串居中,指定填充字符", center("abc", 5, "-="));
        Log.i("字符串居中,长度不对称", center("abc", 6, "-="));
    }

    /**
     * 重复
     */
    @Test
    public void testRepeat() {
        Log.i("字符重复3次", repeat('a', 3));
        Log.i("字符串重复3次", repeat("abc", 3));
        Log.i("字符串重复0次", repeat("abc", 0));
        Log.i("字符串重复-1次", repeat("abc", -1));

        Log.i("重复字符串时,加入分割符", repeat("abc", ",", 3));
    }

    /**
     * 字符串包裹
     */
    @Test
    public void testWrap() {
        Log.i("字符串包裹,无论如何都包裹", wrap("=abc=", "="));
        Log.i("字符串包裹,如果不存在才会包裹", wrapIfMissing("=abc=", "="));

        Log.i("如果没有suffixes后缀,则添加后缀suffix", appendIfMissing("abc", "~", "-", "="));
        Log.i("如果没有suffixes后缀,则添加后缀suffix", appendIfMissing("abc-", "~", "-", "="));
        Log.i("prependIfMissing", prependIfMissing("abc", "q:", "Q:", "q:"));

        Log.i("解除字符串的包裹", unwrap("==a==", "="));
    }

    /**
     * 反转
     */
    @Test
    public void testReverse() {
        Log.i("字符串反转", reverse("abc"));
        Log.i("使用分割符反转", reverseDelimited("a-a,b,c", ','));
    }

    /**
     * 大小写转换
     */
    @Test
    public void testCase() {
        Log.i("大写转换", upperCase("abc"));
        Log.i("小写转换", lowerCase("ABC"));
        Log.i("大小写反转", swapCase("Abc"));

        Log.i("指定时区,从而指定不同语言的大小写字母", upperCase("abc", Locale.CHINA));

        Log.i("首字母大写", capitalize("abc"));
        Log.i("首字母小写", uncapitalize("ABC"));
    }

    /**
     * 缩短省略
     * 比如一个长度特别长的字符串展示时要使用...的方式展示,最短的省略大小为4,否则会抛IllegalArgumentException
     */
    @Test
    public void testAbbreviate() {
        Log.i("获取字符串缩写", abbreviate("中华人民共和国", 6));
        Log.i("获取字符串缩写", abbreviate("My Home Page", 8));
        Log.i("获取字符串缩写,指定偏移量", abbreviate("我叫李四,今年20岁了,我喜欢很多很多好吃的", 5, 10));
        Log.i("获取字符串缩写,缩略中部,上面都是尾部或者头部,可以指定缩略符号", abbreviateMiddle("我叫李四,今年20岁了,我喜欢很多很多好吃的", "...", 10));
    }

    /**
     * 匹配计数
     */
    @Test
    public void testCount() {
        Log.i("匹配计数,查找a在abcabc中出现的次数", countMatches("abcabc", "a"));
        Log.i("匹配计数,查找a在abcabc中出现的次数", countMatches("abcabc", 'a'));
    }

}

BooleanUtils

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.BooleanUtils;
import org.junit.Test;

import static org.apache.commons.lang3.BooleanUtils.*;
import static java.lang.Boolean.*;

/**
 * BooleanUtilsDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-05-19 1:26
 */
public class BooleanUtilsDemo {

    /**
     * 判断方法
     */
    @Test
    public void testIs() {
        // 三个方法没有区别,主要在于使用时语义的不同
        Log.i("判断是否为true", isTrue(Boolean.TRUE));
        Log.i("判断是否不为false", isNotTrue(Boolean.FALSE));
        Log.i("判断是否为false", isFalse(Boolean.FALSE));
        Log.i("判断是否不为true", isNotFalse(Boolean.TRUE));
    }

    /**
     * 比较
     */
    @Test
    public void testCompare() {
        Log.i("比较 相同返回0", BooleanUtils.compare(false, false));
        Log.i("比较", BooleanUtils.compare(true, false));
        Log.i("比较", BooleanUtils.compare(false, true));
    }

    /**
     * 将其他类型转换为boolean类型
     */
    @Test
    public void testToBoolean() {
        Log.i("int -> boolean 1", toBoolean(1));
        Log.i("int -> boolean -1", toBoolean(-1));
        Log.i("int -> boolean 0", toBoolean(0));
        Log.i("int -> boolean 定义true值和false值,如果不匹配则会抛出IllegalArgumentException",
                toBoolean(100, 100, 200));
        Log.i("Integer -> boolean 定义true值和false值,如果不匹配则会抛出IllegalArgumentException",
                toBoolean(Integer.valueOf(100), Integer.valueOf(100), Integer.valueOf(200)));

        Log.i("string -> boolean true", toBoolean("true"));
        Log.i("string -> boolean false", toBoolean("false"));
        String str1 = null;
        Log.i("string -> boolean abc", toBoolean("abc"));
        Log.i("string -> boolean null", toBoolean(str1));
        Log.i("string -> boolean (empty string)", toBoolean(""));
        Log.i("string -> boolean (blank string)", toBoolean(" "));
        Log.i("string -> boolean false 定义true值和false值,如果不匹配则会抛出IllegalArgumentException",
                toBoolean("open", "open", "close"));

        Log.i("Boolean -> boolean true", toBoolean(Boolean.TRUE));
        Log.i("Boolean -> boolean false", toBoolean(Boolean.FALSE));

        Log.i("all -> BooleanObject", toBooleanObject(1));
    }

    /**
     * 将boolean类型转换为int类型
     * int 默认 0false 1true
     */
    @Test
    public void testToInteger() {
        Log.i("boolean -> int true", toInteger(true));
        Log.i("boolean -> int false", toInteger(false));
        Log.i("boolean -> Integer true", toIntegerObject(true));
        Log.i("Boolean -> Integer false", toIntegerObject(false));
        Log.i("boolean -> Integer 定义true和false对应的int值", toInteger(false, 100,200));
    }

    @Test
    public void testToString() {
        Boolean nb = null;
        Log.i("boolean -> string 必须指定true和false对应的string值,如果为null会抛出空指针异常",
                BooleanUtils.toString(true, "open", "close"));
        Log.i("boolean -> string 必须指定true和false对应的string值,指定null对应的值",
                BooleanUtils.toString(nb, "open", "close", "sorry"));

        // 除此之外,还提供了许多默认的返回设置,比如yes/no,on/off等
        Log.i("true/false", toStringTrueFalse(true));
        Log.i("yes/no", toStringYesNo(true));
        Log.i("on/off", toStringOnOff(true));
    }

    @Test
    public void testLogic() {
        Log.i("与 and", BooleanUtils.and(new Boolean[]{true, false}));
        Log.i("或 or", BooleanUtils.or(new Boolean[]{true, false}));
        Log.i("抑或 xor", BooleanUtils.xor(new Boolean[]{true, false}));
    }

    @Test
    public void testDefault() {
        Boolean b = null;
        Log.i("设置如果为null的默认值",toBooleanDefaultIfNull(b, true));
    }
}

CharUtilsDemo

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.CharUtils;
import static org.apache.commons.lang3.CharUtils.*;
import org.junit.Test;

/**
 * CharUtilsDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-05-19 22:10
 */
public class CharUtilsDemo {

    /**
     * 常量
     */
    @Test
    public void testConstant() {
        char nul = CharUtils.NUL; // \0
        char cr = CharUtils.CR; // \r
        char lf = CharUtils.LF; // \n
    }

    /**
     * 判断字符类型
     */
    @Test
    public void testIs() {
        Log.i("判断字符是否为ASCII字符", isAscii('a'));
        Log.i("判断字符是否为ASCII字母", isAsciiAlpha('a'));
        Log.i("判断字符是否为ASCII小写字母", isAsciiAlphaLower('a'));
        Log.i("判断字符是否为ASCII大写字母", isAsciiAlphaUpper('A'));
        Log.i("判断字符是否为ASCII数字", isAsciiNumeric('1'));
        Log.i("判断字符是否为ASCII字母或者数字", isAsciiAlphanumeric('1'));
        Log.i("判断字符是否为ASCII打印字符", isAsciiPrintable('\n'));
        Log.i("判断字符是否为ASCII控制字符", isAsciiControl('\n'));
    }

    /**
     * 转换
     */
    @Test
    public void testTo() {
        Log.i("string -> one char, 如果string为null或者empty会抛出非法参数异常", toChar("abc"));
        Log.i("string -> one char, 如果string为null或者empty输出默认值", toChar("", 'a'));

        Log.i("char -> int, 如果字符不是数字,则会抛出非法参数异常", toIntValue('0'));
        Log.i("char -> int, 如果字符不是数字,返回默认值", toIntValue('a', 0));

        Log.i("char -> string", CharUtils.toString('a'));
        Character a = null;
        Log.i("char -> string, 如果参数是null返回null", CharUtils.toString(a));

    }

    /**
     * 获取unicode码
     */
    @Test
    public void testUnicode() {
        Log.i("获取字符的unicode码",CharUtils.unicodeEscaped('a'));
    }
}

NumberUtilsDemo

package lang3;

import lang3.util.Log;
import static org.apache.commons.lang3.math.NumberUtils.*;
import org.junit.Test;

/**
 * NumberUtilsDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-05-19 22:44
 */
public class NumberUtilsDemo {

    /**
     * 判断方法
     * 判断字符串是否是纯数字字符串
     * 判断字符串是否可以被解析为数字,小数、负数可以被解析
     * 判断字符串是否是一个有效的Java数值,包含0x预选项、八进制、科学计数、标点符等
     */
    @Test
    public void testIs() {
        Log.i("判断字符串是否为纯数字字符串",isDigits("123"));
        Log.i("判断字符串是否为纯数字字符串,不可包含小数点",isDigits("123.1"));
        Log.i("判断字符串是否为纯数字字符串,不可包含符号",isDigits("-123"));

        Log.i("判断字符串是否可以解析为数字,小数可以被解析", isParsable("1123.1"));
        Log.i("判断字符串是否可以解析为数字,符数可以被解析", isParsable("-1123.1"));
        Log.i("判断字符串是否可以解析为数字,其他包含字母的不可以被解析", isParsable("0x1123.1"));
        Log.i("判断字符串是否可以解析为数字,尾部包含字母不可以被解析", isParsable("123a"));

        Log.i("判断字符串是否可以被解析为java数字,负数、小数", isCreatable("-1.12"));
        Log.i("判断字符串是否可以被解析为java数字,其他进制表示", isCreatable("0x23"));
        Log.i("判断字符串是否可以被解析为java数字,科学记数法表示", isCreatable("12e12"));
        Log.i("判断字符串是否可以被解析为java数字,尾部包含字母,不可以被解析", isCreatable("-1.12a"));
    }

    @Test
    public void testToByteIntLong() {
        Log.i("string -> int 负数字符串可以转换,如果无法解析返回默认值0 ", toInt("-1", 0));
        Log.i("string -> int 其他进制不可以转换 ", toInt("0x123", 0));
        Log.i("string -> int 小数字符串不可以转换", toInt("12.3", 0));
        Log.i("string -> int 尾部不可以包含字母", toInt("123a", 0));

        // toByte toShort toLong  类似
    }

    @Test
    public void testFloatDouble() {
        Log.i("string -> float,如果无法解析则会返回0.0", toFloat("123.1"));
        Log.i("string -> float", toFloat("-123.1", 0f));
        Log.i("string -> float", toFloat("-123.1a", 0f));

        // toDouble类似
    }

    @Test
    public void testCreate() {
        Log.i("string -> number", createNumber("-123.1"));
        Log.i("string -> number 支持其他进制", createNumber("0x123"));
        Log.i("string -> number 支持科学记数法", createNumber("9e1242"));

        // 强大
        Log.i("string -> Integer 如果解析失败,会抛出NumberFormatException", createInteger("-123"));

        // BigDecimal和BigInteger
        Log.i("string -> BigInteger", createBigDecimal("9e1234"));
    }

    @Test
    public void testCompare() {
        Log.i("比较", compare(1, 2));
        Log.i("最大值", max(1, 4,3.4));
        Log.i("最小值", min(1, 2,3));

        //int[] arr = null;
        //Log.i("如果出现null,则会抛出非法参数异常", max(arr));
    }

}

ArrayUtilsDemo

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Test;

import java.util.Map;

import static org.apache.commons.lang3.ArrayUtils.*;

/**
 * ArrayUtilsDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-05-19 0:57
 */
public class ArrayUtilsDemo {

    private char[] nullArr = null;
    private char[] emptyArr = new char[]{};

    /**
     * 数组判断工具
     * 判断是否为空数组
     * 判断数组长度是否相同
     * 判断数组是否已经排序
     */
    @Test
    public void testIs() {
        Log.i("判断数组是否为空", isEmpty(emptyArr));
        Log.i("判断数组是否不为空", isNotEmpty(emptyArr));
        Log.i("判断数组是否为空,如果为null,同样代表数组为空", isEmpty(nullArr));

        Log.i("判断数组长度是否一致,提供了Object[]与Object[]的比较,可以比较不同的类型", isSameLength(new char[]{'a', 'b'}, new char[]{'1', '2'}));
        Log.i("判断数组长度是否一致,如果两个数组都为null,则代表有相同的length", isSameLength(nullArr, nullArr));

        Log.i("判断数组是否排序,使用compare函数进行判断,对象类型需要实现Comparable", isSorted(new char[]{'a', 'b', 'c'}));
    }

    /**
     * 打印数组
     */
    @Test
    public void testToString() {
        Log.i(ArrayUtils.toString(new int[]{1, 2, 3, 4}));
    }

    /**
     * 基本类型数组 转换 对象类型数组
     */
    @Test
    public void testToObject() {
        Integer[] integers = toObject(new int[]{1, 2, 3, 4});
        Log.i(integers);
    }

    /**
     * 对象类型数组 转换基本类型数组 ,如果出现null会出现空指针异常
     */
    @Test
    public void testToPrimitive() {
        boolean[] booleans = toPrimitive(new Boolean[]{true, false, true, null});
        Log.i(booleans);
    }

    @Test
    public void testToArray() {
        Integer[] integers = null;
        Log.i("nullToEmpty, 如果数组对象为null,则返回一个空的数组", nullToEmpty(integers));
        Log.i("ToArray", toArray("a", "b", "b"));
        Log.i("ToStringArray", toStringArray(new String[]{null, null}, "null~"));
    }

    /**
     * 将二维数组转换为map
     */
    @Test
    public void testToMap() {
        String[][] arr = new String[][]{{"a", "b"}, {"aa", "bb"}};
        Map<Object, Object> map = toMap(arr);
        Log.i("转换为Map", map);
    }

    /**
     * 元素位置查找
     */
    @Test
    public void testIndex() {
        char[] as = new char[]{'a', 'b', 'a'};
        Log.i("从前往后查找数组元素a", indexOf(as, 'a'));
        Log.i("从前往后查找数组元素a, 指定开始查找位置为1", indexOf(as, 'a', 1));

        Log.i("从后往前查找数组元素a", lastIndexOf(as, 'a'));
        Log.i("从后往前查找数组元素a, 指定开始查找位置为1", lastIndexOf(as, 'a', 1));
    }

    /**
     * 判断是否包含
     */
    @Test
    public void testContains() {
        char[] as = new char[]{'a', 'b', 'a'};
        Log.i("判断元素是否被包含", contains(as, 'a'));
    }

    /**
     * 元素尾部增添
     */
    @Test
    public void testAdd() {
        Log.i("将单个元素添加到数组中", add(new char[]{}, 'a'));
        Log.i("将多个元素添加到另一个数组中", addAll(new char[]{}, 'a', 'b'));
    }

    /**
     * 元素插入 插入到指定的位置
     */
    @Test
    public void testInsert() {
        String[] strs = new String[]{"a", "b", "c"};
        Log.i("将元素插入到数组的指定位置", insert(1, strs, "c", "c"));
    }

    /**
     * 元素删除
     */
    @Test
    public void testRemove() {
        Log.i("从数组中删除指定下标的元素", remove(new char[]{'a', 'b'}, 1));
        Log.i("从数组中删除指定的多个下标的元素", removeAll(new char[]{'a', 'b'}, 0, 1));
        Log.i("从数组中删除指定的元素, 只会删除第一个", removeElement(new char[]{'a', 'b', 'a'}, 'a'));
        Log.i("从数组中删除多个指定的元素, 只会删除第一个", removeElements(new char[]{'a', 'b', 'a'}, 'a', 'b'));
        Log.i("从数组中删除所有的指定的元素", removeAllOccurences(new char[]{'a', 'b', 'a'}, 'a'));
    }

    @Test
    public void testOpr() {
        int[] ints = new int[]{1, 2, 4, 5};
        reverse(ints);
        Log.i("反转数组", ints);

        int[] ints1 = new int[]{1, 2, 4, 5};
        shift(ints1, 1);
        Log.i("移动数组,数组后移1位", ints1);
        shift(ints1, -1);
        Log.i("移动数组,数组前移1位", ints1);

        int[] ints2 = new int[]{1, 2, 4, 5};
        shuffle(ints2);
        Log.i("随机打乱数组", ints2);

        int[] ints3 = new int[]{1, 2, 4, 5};
        swap(ints3, 1, 2);
        Log.i("数组交换", ints3);
        swap(ints3, 1, 2,1);
        Log.i("数组交换,指定偏移量", ints3);

        Log.i("截取数组", subarray(new int[]{1, 2, 3, 4, 5}, 1, 3));
    }
}

DateUtils

  • Calendar: 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

  • TimeZone: 表示时区偏移量。

  • Locale: 表示了特定的地理、政治和文化地区。需要 Locale 来执行其任务的操作称为语言环境敏感的操作,它使用 Locale 为用户量身定制信息。

  • SimpleDateFormat: 主要是用来格式化Date,用过之后就会发现,它其实不完善,对Calendar提供的支持很少.

经历几个项目发现apache提供的第三方扩展类库,org.apache.commons.lang.time包比较好用,可以将程序中时间处理变的简单一点,提高你的开发效率,下面介绍下常用的方法和具体使用。

org.apache.commons.lang.time 包括以下几个类:

  1. DateFormatUtils 【格式化Calendar与Date并依赖于 FastDateFormat】

  2. DateUtils 【围绕Calendar与Date的实用方法】

  3. DurationFormatUtils 【毫秒数格式化Calendar与Date】

  4. FastDateFormat 【线程安全的SimpleDateFormat】

  5. StopWatch 【提供一个方便的定时的API 】

TimeConstant

package lang3.date;

/**
 * 时间相关常量
 * <p>
 *
 * @author Feathers
 * @date 2017-12-07 11:40
 */
public class TimeConstant {

    /**
     * yyyy-MM-dd HH:mm:ss
     */
    public static final String TARGET_1 = "yyyy-MM-dd HH:mm:ss";

    /**
     * yyyy-MM-dd HH:mm
     */
    public static final String TARGET_2 = "yyyy-MM-dd HH:mm";

    /**
     * yyyy-MM-dd
     */
    public static final String TARGET_3 = "yyyy-MM-dd";

    /**
     * yyyy年MM月dd日
     */
    public static final String TARGET_4 = "yyyy年MM月dd日";

    /**
     * yyyy年MM月dd日 HH:mm
     */
    public static final String TARGET_5 = "yyyy年MM月dd日 HH:mm";

    /**
     * yyyy年MM月dd日 HH:mm:ss
     */
    public static final String TARGET_6 = "yyyy年MM月dd日 HH:mm:ss";

    /**
     * yyyyMMddHHmmss
     */
    public static final String TARGET_7 = "yyyyMMddHHmmss";

}

FastDateFormatDemo

package lang3.date;

import lang3.util.Log;
import org.apache.commons.lang3.time.FastDateFormat;
import org.junit.Test;

import java.util.Date;

/**
 * FastDateFormatDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-05-21 17:49
 */
public class FastDateFormatDemo {

    @Test
    public void test() {
        FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd");
        String format = fdf.format(new Date());
        Log.i(format);
    }

    @Test
    public void testPattern() {
        // 使用fast date format 直接格式化日期
        FastDateFormat fastDateFormat = FastDateFormat.getInstance(TimeConstant.TARGET_7);
        System.out.println(fastDateFormat.format(new Date()));
    }
}

DateFormatUtilsDemo

package lang3.date;

import lang3.util.Log;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.Test;

import java.util.Calendar;
import java.util.Date;

/**
 * DateFormatUtilsDemo
 * 日期格式化工具类
 * <p>
 *
 * @author Feathers
 * @date 2018-05-21 16:55
 */
public class DateFormatUtilsDemo {

    private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd-HH-mm-ss-SSS";

    @Test
    public void test() {
        Log.i("Date类型格式化", DateFormatUtils.format(new Date(), DATE_FORMAT_PATTERN));
        Log.i("Calender类型格式化", DateFormatUtils.format(Calendar.getInstance(), DATE_FORMAT_PATTERN));
        Log.i("时间戳类型格式化", DateFormatUtils.format(new Date().getMinutes(), DATE_FORMAT_PATTERN));
    }

    @Test
    public void testPattern() {
        // DateFormatUtils 提供了几种时间格式
        Date date = new Date();
        System.out.println("ISO_8601_EXTENDED_DATE_FORMAT:" + DateFormatUtils.format(date, DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.getPattern()));
        System.out.println("ISO_8601_EXTENDED_DATETIME_FORMAT:" + DateFormatUtils.format(date, DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.getPattern()));
        System.out.println("ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT:" + DateFormatUtils.format(date, DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.getPattern()));
        System.out.println("ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT:" + DateFormatUtils.format(date, DateFormatUtils.ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT.getPattern()));
        System.out.println("SMTP_DATETIME_FORMAT:" + DateFormatUtils.format(date, DateFormatUtils.SMTP_DATETIME_FORMAT.getPattern()));

        // 上面的代码等同于
        System.out.println(DateFormatUtils.ISO_8601_EXTENDED_TIME_TIME_ZONE_FORMAT.format(date));
    }

}

DateUtilsDemo

package lang3.date;

import lang3.util.Log;
import org.junit.Test;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import static org.apache.commons.lang3.time.DateUtils.*;

/**
 * DateUtilsDemo
 * 常用日期操作工具类
 * <p>
 *
 * @author Feathers
 * @date 2018-05-20 9:32
 */
public class DateUtilsDemo {

    @Test
    public void testConstant() {
        // 毫秒数
        Object[] MILLIS = new Object[]{
                MILLIS_PER_SECOND, // 每秒的毫秒数
                MILLIS_PER_MINUTE, // 每分钟的毫秒数
                MILLIS_PER_HOUR, // 每小时的毫秒数
                MILLIS_PER_DAY // 每天的毫秒数
        };
    }

    /**
     * 判断方法
     */
    @Test
    public void testIs() {
        Log.i("是否是同一天", isSameDay(new Date(), new Date()));
        Log.i("判断即时时间,即毫秒值是否相同", isSameInstant(new Date(), new Date()));
        Log.i("判断两个日历本地时间是否相同", isSameLocalTime(Calendar.getInstance(), Calendar.getInstance()));
    }

    @Test
    public void testParseDate() {
        try {
            Date date = parseDate("2018-01-03", "yyyy-MM-dd", "yyyyMMdd");
            Log.i("将字符串使用相应的一个或者多个pattern解析为对象", date);

            Date date1 = parseDate("1995年09月02日", Locale.CHINA, "yyyy年MM月dd日");
            Log.i("将字符串使用相应的一个或者多个pattern解析为date对象,并且指定Locale,如果locale为null,则使用系统默认的locale", date1);

            Date date2 = parseDateStrictly("2018-01-03", "yyyy-MM-dd", "yyyyMMdd");
            Log.i("使用严格模式解析,解析器解析严格不允许的日期, 如:\"February 942, 1996\" ", date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 日期修改 add
     */
    @Test
    public void testAdd() {
        Log.i("获取去年今天", addYears(new Date(), -1));
        Log.i("获取明年今天", addYears(new Date(), 1));

        Log.i("获取上个月今天", addMonths(new Date(), -1));
        Log.i("获取下个月今天", addMonths(new Date(), 1));

        Log.i("获取上周今天", addWeeks(new Date(), -1));
        Log.i("获取下周今天", addWeeks(new Date(), 1));

        Log.i("获取昨天", addDays(new Date(), -1));
        Log.i("获取明天", addDays(new Date(), 1));

        Log.i("获取一小时前", addHours(new Date(), -1));
        Log.i("获取一小时后", addHours(new Date(), 1));

        Log.i("获取一分钟前", addMinutes(new Date(), -1));
        Log.i("获取一分钟后", addMinutes(new Date(), 1));

        Log.i("获取一秒钟前", addSeconds(new Date(), -1));
        Log.i("获取一秒钟后", addSeconds(new Date(), 1));

        Log.i("获取一毫秒前", addMilliseconds(new Date(), -1));
        Log.i("获取一毫秒后", addMilliseconds(new Date(), 1));

    }

    /**
     * 根据阈值向上舍入 ceiling
     */
    @Test
    public void testCeiling() {
        Log.i("舍入到年", ceiling(new Date(), Calendar.YEAR));
        Log.i("舍入到月", ceiling(new Date(), Calendar.MONTH));
    }

    /**
     * 根据阈值四舍五入
     */
    @Test
    public void testRound() {
        Log.i("四舍五入到年", round(new Date(), Calendar.YEAR));
        Log.i("四舍五入到月", round(new Date(), Calendar.MONTH));
    }

    /**
     * 截取时间
     */
    @Test
    public void testTruncate() {
        Log.i("截取到年", truncate(new Date(), Calendar.YEAR));
        Log.i("截取到月", truncate(new Date(), Calendar.MONTH));
    }

    /**
     * 比较
     */
    @Test
    public void testEquals() {
        Log.i("判断两个日期的月是否相同", truncatedEquals(new Date(), new Date(), Calendar.MONTH));
        Log.i("比较两个日期的月份的大小,相同返回0", truncatedCompareTo(new Date(), new Date(), Calendar.MONTH));
    }

    /**
     * 获取方法
     * 返回指定范围内的xx数,比如指定年的月数
     */
    @Test
    public void testGet() {
        Log.i("获取一年中的天数", getFragmentInDays(new Date(), Calendar.YEAR));
    }
}

ClassPathUtilsDemo

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.ClassPathUtils;
import org.junit.Test;

/**
 * ClassPathUtilsDemo
 * 路径相关操作
 * <p>
 *
 * @author Feathers
 * @date 2018-05-22 10:13
 */
public class ClassPathUtilsDemo {

    @Test
    public void test() {
        String s = ClassPathUtils.toFullyQualifiedName(ClassPathUtilsDemo.class, "test.properties");
        Log.i("获取与ClassPathUtils本类相同路径下的静态文件的全限定名", s);

        String s1 = ClassPathUtils.toFullyQualifiedName(ClassPathUtils.class.getPackage(), "test.properties");
        Log.i("获取与ClassPathUtils本类相同包下的静态文件的全限定名", s1);

        String s2 = ClassPathUtils.toFullyQualifiedPath(ClassPathUtilsDemo.class, "test.properties");
        Log.i("获取与ClassPathUtils本类相同路径下的静态文件的路径", s2);

        String s3 = ClassPathUtils.toFullyQualifiedPath(ClassPathUtils.class.getPackage(), "test.properties");
        Log.i("获取与ClassPathUtils本类相同包下的静态文件的路径", s3);
    }

}

ClassUtilsDemo

package lang3;

import lang3.util.Log;
import org.apache.commons.lang3.ClassUtils;
import org.junit.Test;

import static org.apache.commons.lang3.ClassUtils.*;

/**
 * ClassUtilsDemo
 * 不直接操作反射就可以处理class
 * <p>
 *
 * @author Feathers
 * @date 2018-05-22 10:27
 */
public class ClassUtilsDemo {

    /**
     * 常用常量
     */
    @Test
    public void testConstant() {
        Log.i("内部类分隔符 string类型", ClassUtils.INNER_CLASS_SEPARATOR);
        Log.i("内部类分隔符 char类型", ClassUtils.INNER_CLASS_SEPARATOR_CHAR);
        Log.i("包分隔符 string类型", ClassUtils.PACKAGE_SEPARATOR);
        Log.i("包分隔符 char类型", ClassUtils.PACKAGE_SEPARATOR_CHAR);
    }

    /**
     * 获取方法
     */
    @Test
    public void testGet() throws Exception {

        Log.i("使用默认类加载器,获取已经初始化的class实例", ClassUtils.getClass("java.util.List"));
        Log.i("使用默认类加载器,获取未初始化的class实例", ClassUtils.getClass("java.util.List", false));
        /*
            注: commons lang getClass方法 也提供了参数classLoader对象,用来设置加载器
         */
    }
}

RandomUtilsDemo

package lang3;

import lang3.util.Log;
import org.junit.Test;

import static org.apache.commons.lang3.RandomUtils.*;

/**
 * RandomUtilsDemo
 * 随机生成工具类
 * <p>
 *
 * @author Feathers
 * @date 2018-05-19 22:34
 */
public class RandomUtilsDemo {

    @Test
    public void testBoolean() {
        Log.i("随机生成一个boolean值", nextBoolean());
    }

    @Test
    public void testInt() {
        Log.i("随机生成一个int值", nextInt());
        Log.i("随机生成一个int值,设置范围[start, end)", nextInt(1, 10));
    }

    @Test
    public void testLong() {
        Log.i("随机生成一个long值", nextLong());
        Log.i("随机生成一个long值,设置范围[start, end)", nextLong(1, 10));
    }

    @Test
    public void testFloat() {
        Log.i("随机生成一个float值", nextFloat());
        Log.i("随机生成一个float值,设置范围[start, end)", nextFloat(10.1f, 12.3f));
    }

    @Test
    public void testDouble() {
        Log.i("随机生成一个double值", nextFloat());
        Log.i("随机生成一个double值,设置范围[start, end)", nextDouble(10.1, 12.3));
    }

    @Test
    public void testBytes() {
        Log.i("随机生成一个bytes数组,指定长度为count", nextBytes(2));
    }
}

builder

ToStringBuilderDemo

package lang3.builder;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * ToStringBuilderDemo
 * <p>
 *
 * @author Feathers
 * @date 2018-06-07 14:14
 */
class ToStringBuilderDemo {

    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setId(1);
        dog.setName("旺财");
        dog.setAge("1");

        System.out.println(dog);
    }

}

class Dog {
    private int id;
    private String name;
    private String age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("id", id)
                .append("name", name)
                .append("age", age)
                .toString();
    }
}

CompareToBuildDemo

package lang3.builder;

import org.apache.commons.lang3.builder.CompareToBuilder;

import java.util.ArrayList;
import java.util.Comparator;

/**
 * CompareToBuildDemo
 * 比较构建
 * <p>
 *
 * @author Feathers
 * @date 2018-06-07 11:44
 */
class CompareToBuildDemo {

    public static void main(String[] args) {
        Employee boss = new Employee(1001, "王老板", Position.BOSS);

        Employee manager1 = new Employee(1002, "张经理", Position.MANAGER);
        Employee manager2 = new Employee(1004, "赵经理", Position.MANAGER);
        Employee stuff1 = new Employee(1003, "李小二", Position.STUFF);
        Employee stuff2 = new Employee(1005, "王小二", Position.STUFF);

        ArrayList<Employee> employees = new ArrayList<Employee>() {{
            this.add(stuff1);
            this.add(manager2);
            this.add(stuff2);
            this.add(manager1);
            this.add(boss);
        }};

        employees.sort(new PositionCompare());
        System.out.println(manager1.compareTo(manager2));
        System.out.println(employees);
    }
}

class Employee implements Comparable<Employee> {

    // 根据进入公司的先后顺序编码的
    private int id;
    private String name;
    private Position position;

    public Employee(int id, String name, Position position) {
        this.id = id;
        this.name = name;
        this.position = position;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Employee{");
        sb.append("id=").append(id);
        sb.append(", name='").append(name).append('\'');
        sb.append(", position=").append(position);
        sb.append('}');
        return sb.toString();
    }

    // 默认的比较器,按照自立排序
    @Override
    public int compareTo(Employee o) {
        return new CompareToBuilder()
                .append(id, o.id) // 先按照资历排序, 倒叙切换两个参数的位置
                .toComparison();
    }
}

// 定义按照职位的比较器
class PositionCompare implements Comparator<Employee> {
    @Override
    public int compare(Employee o1, Employee o2) {
        return new CompareToBuilder()
                .append(o1.getPosition(), o2.getPosition())
                .append(o1.getId(), o2.getId())
                .toComparison();
    }
}

enum Position {
    BOSS, MANAGER, STUFF
}

最后更新于