实现一个简单的字符串工具库

学习编程的一个比较好的方法就是阅读别人优秀的代码,学习别人的代码并尝试自己去实现那些功能,这样对提升自己的编码能力是有十分大的帮助的。这里简单实现一个不依赖于其他库的strutil库。

1.构建一个简单的maven项目

实现一个简单的字符串工具库_第1张图片

2.实现细节

为了使代码更加健壮,一般需要统一处理一下异常的输入,这样在接收异常的输入时,程序不至于直接崩溃掉,由于是工具类,所以私有化构造方法,并将各种实现方法以静态方法的形式实现。

public class StrUtil {

    private static final String[] EMPTY_ARRAY = new String[0];

    private static final Supplier<String> NULL_STRING_MSG = () -> "字符串不能为空";

    private static final Predicate<String> NULL_STRING_PREDICATE = Objects::isNull;

    /**
     * 私有化构造方法
     */
    private StrUtil(){

    }

    /**
     * 验证输入
     * @param value
     * @param predicate
     * @param supplier
     */
    private static void validate(String value, Predicate<String> predicate, final Supplier<String> supplier){
        if(predicate.test(value)){
            throw new IllegalArgumentException(supplier.get());
        }
    }

    /**
     * 验证输入是否为空或者空字符串
     * @param value
     * @return
     */
    private static boolean isNullOrEmpty(String value){
        return value == null || value.isEmpty();
    } 
}
  • 将字符串数组中的值添加到字符串后
    private static String appendArray(String value, final String[] appends){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(appends == null || appends.length == 0){
            return value;
        }
        StringJoiner joiner = new StringJoiner(""); // 添加字符串时,以""为分割符
        for(String append : appends){
            joiner.add(append);
        }
        return value + joiner.toString();
    }

    /**
     * 将字符串数组中的值添加到字符串后
     * @param value
     * @param appends
     * @return
     */
    public static String append(String value, final String... appends){
        return appendArray(value, appends);
    }
  • 获取指定的两个字符串之间的字符串
    /**
     * 获取指定的两个字符串之间的字符串
     * @param value
     * @param start
     * @param end
     * @return
     */
    public static String[] between(String value, final String start, final String end){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        validate(start, NULL_STRING_PREDICATE, () -> "start不能为空");
        validate(end, NULL_STRING_PREDICATE, () -> "end不能为空");

        String[] parts = value.split(end);
        return Arrays.stream(parts)
                .filter(subPart -> subPart.contains(start))
                .map(subPart -> subPart.substring(subPart.indexOf(start) + start.length()))
                .toArray(String[]::new);
    }
  • 将字符串转化成字符串数组 “123” -> [“1”, “2”, “3”]
    /**
     * 将字符串转化成字符串数组   "123" -> ["1", "2", "3"]
     * @param value
     * @return
     */
    public static String[] chars(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.split("");
    }
  • 将字符串中的空白字符全部替换成一个空格
    /**
     * 将字符串中的空白字符全部替换成一个空格
     * @param value
     * @return
     */
    public static String collapseWhitespace(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.trim().replaceAll("\\s\\s+", " ");
    }
  • 判断子串是否包含在字符串中,默认忽略大小写
    /**
     * 判断子串是否包含在字符串中
     * @param value
     * @param sub
     * @param caseSensitive
     * @return
     */
    private static boolean contains(String value, final String sub, final boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(caseSensitive){
            return value.contains(sub);
        }
        return value.toLowerCase().contains(sub.toLowerCase());
    }

    /**
     * 判断子串是否包含在字符串中,默认忽略大小写
     * @param value
     * @param sub
     * @return
     */
    public static boolean contains(String value, final String sub){
        return contains(value, sub, false);
    }
  • 判断所有的子串是否都包含在字符串中,默认忽略大小写
    /**
     * 判断所有的子串是否都包含在字符串中
     * @param value
     * @param subs
     * @param caseSensitive
     * @return
     */
    private static boolean containsAll(String value, final String[] subs, final boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return Arrays.stream(subs).allMatch(sub -> contains(value, sub, caseSensitive));
    }

    /**
     * 判断所有的子串是否都包含在字符串中,默认忽略大小写
     * @param value
     * @param subs
     * @return
     */
    public static boolean containsAll(String value, final String[] subs){
        return containsAll(value, subs, false);
    }
  • 判断一个或者多个子串包含在字符串中,默认忽略大小写
    /**
     * 判断一个或者多个子串包含在字符串中
     * @param value
     * @param subs
     * @param caseSensitive
     * @return
     */
    public static boolean containsAny(String value, final String[] subs, final boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return Arrays.stream(subs).anyMatch(sub -> contains(value, sub, caseSensitive));
    }

    /**
     * 判断一个或者多个子串包含在字符串中,默认忽略大小写
     * @param value
     * @param subs
     * @return
     */
    public static boolean containsAny(String value, final String[] subs){
        return containsAny(value, subs);
    }
  • 统计一个子串在字符串中出现的次数,默认区分大小写,默认统计一次越过真个子串
    public static long countSubstr(String value, final String sub, boolean allowOverlapping, long count){
        int position = value.indexOf(sub);
        if(position == -1){
            return count;
        }
        int offset;
        // 是否完整越过子串
        if(!allowOverlapping){
            offset = position + sub.length();
        }else{
            offset = position + 1;
        }
        return countSubstr(value.substring(offset), sub, allowOverlapping, ++count);
    }

    public static long countSubstr(String value, final String sub, final boolean caseSensitive, boolean allowOverLapping){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return countSubstr(caseSensitive ? value : value.toLowerCase(), caseSensitive ? sub : sub.toLowerCase(),
                allowOverLapping, 0L);
    }

    /**
     * 统计一个子串在字符串中出现的次数,默认区分大小写,默认统计一次越过真个子串
     * @param value
     * @param sub
     * @return
     */
    public static long countSubstr(String value, final String sub){
        return countSubstr(value, sub, true, false);
    }
  • 判断字符串是否一某个子串结尾,默认忽略大小写
    public static boolean endsWith(String value, final String sub, final boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        int remainingLength = value.length() - sub.length();
        if(caseSensitive){
            return value.indexOf(sub, remainingLength) > -1;
        }
        return value.toLowerCase().indexOf(sub.toLowerCase(), remainingLength) > -1;
    }

    /**
     * 判断字符串是否一某个子串结尾,默认忽略大小写
     * @param value
     * @param sub
     * @return
     */
    public static boolean endsWith(String value, final String sub){
        return endsWith(value, sub, false);
    }
  • 确认字符串以一个子串开头,如果不是则将子串添加到字符串头部,默认区分大小写
    public static String ensureStart(String value, final String prefix, final boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(caseSensitive){
            return value.startsWith(prefix) ? value : prefix + value;
        }
        return value.toLowerCase().startsWith(prefix.toLowerCase()) ? value.toLowerCase() : prefix.toLowerCase() + value.toLowerCase();
    }

    /**
     * 确认字符串以一个子串开头,如果不是则将子串添加到字符串头部,默认区分大小写
     * @param value
     * @param prefix
     * @return
     */
    public static String ensureStart(String value, final String prefix){
        return ensureStart(value, prefix, true);
    }
  • 以utf-8编码与解码
    /**
     * 以utf-8编码字符串
     * @param value
     * @return
     */
    public static String base64Encode(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 解码
     * @param value
     * @return
     */
    public static String base64Decode(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return new String(Base64.getDecoder().decode(value), StandardCharsets.UTF_8);
    }
  • 返回字符串的第一个子串,确保一定返回一个对象 & 返回字符串的最后一个子串,确保一定返回一个对象
    public static Optional<String> first(String value, final int n){
        return Optional.ofNullable(value).filter(v -> !v.isEmpty()).map(v -> v.substring(0, n));
    }

    /**
     * 返回字符串的第一个子串
     * @param value
     * @return
     */
    public static Optional<String> head(String value){
        return first(value, 1);
    }

    /**
     * 返回字符串的最后一个子串,确保一定返回一个对象
     * @param value
     * @return
     */
    public static Optional<String> tail(String value){
        return Optional.ofNullable(value).filter(v -> !v.isEmpty()).map(v -> last(v, v.length() - 1));
    }
  • 判断子串从指定得到位置起,是否包含在字符串中
    /**
     * 判断子串从指定得到位置起,是否包含在字符串中
     * @param value
     * @param sub
     * @param offset
     * @param caseSensitive
     * @return
     */
    public static int indexOf(String value, final String sub, int offset, boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(caseSensitive){
            return value.indexOf(sub, offset);
        }
        return value.toLowerCase().indexOf(sub.toLowerCase(), offset);
    }
  • 将子串插入到字符串指定的位置
    /**
     * 将子串插入到字符串指定的位置
     * @param value
     * @param sub
     * @param index
     * @return
     */
    public static String insert(String value, String sub, int index){
        validate(value, NULL_STRING_PREDICATE,NULL_STRING_MSG);
        validate(sub, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        if(index > value.length()){
            return value;
        }
        return append(value.substring(0, index), sub, value.substring(index));
    }
  • 检验一个字符串全是大写字母 & 检验一个字符串全是小写字母
    /**
     * 检验一个字符串全是大写字母
     * @param value
     * @return
     */
    public static boolean isUpperCase(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        for(int i = 0; i < value.length(); i++){
            if(Character.isLowerCase(value.charAt(i))){
                return false;
            }
        }
        return true;
    }

    /**
     * 检验一个字符串全是小写字母
     * @param value
     * @return
     */
    public static boolean isLowerCase(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        for(int i = 0; i < value.length(); i++){
            if(Character.isUpperCase(value.charAt(i))){
                return false;
            }
        }
        return true;
    }
  • 返回最后的n个字符串
    /**
     * 返回最后的n个字符串
     * @param value
     * @param n
     * @return
     */
    public static String last(String value, int n){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        if(n > value.length()){
            return value;
        }
        return value.substring(value.length() - n);
    }
  • 在字符串末尾填充多个pad & 在字符串头部填充多个pad
    /**
     * 将字符串重复multiplier次
     * @param value
     * @param multiplier
     * @return
     */
    public static String repeat(String value, final int multiplier){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        return Stream.generate(() -> value).limit(multiplier).collect(Collectors.joining());
    }

    /**
     * 在字符串末尾填充多个pad
     * @param value
     * @param pad
     * @param length
     * @return
     */
    public static String rightPad(String value, String pad, int length){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        validate(pad, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(value.length() > length){
            return value;
        }

        return append(value, repeat(pad, length - value.length()));
    }

    /**
     * 在字符串头部填充多个pad
     * @param value
     * @param pad
     * @param length
     * @return
     */
    public static String leftPad(String value, String pad, int length){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        validate(pad, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(value.length() > length){
            return value;
        }
        return append(repeat(pad, length - value.length()), value);
    }
  • 判断一个对象是否为字符串
    /**
     * 判断一个对象是否为字符串
     * @param value
     * @return
     */
    public static boolean isString(Object value){
        if(Objects.isNull(value)){
            throw new IllegalArgumentException("字符串不能为空");
        }
        return value instanceof String;
    }
  • 去除左侧的空格 & 去除右侧的空格 & 去除左侧右侧的空格
    /**
     * 去除左侧的空格
     * @param value
     * @return
     */
    public static String leftTrim(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.replaceAll("^\\s+", "");
    }

    /**
     * 去除右侧的空格
     * @param value
     * @return
     */
    public static String rightTrim(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.replaceAll("\\s+$", "");
    }

    /**
     * 去除左侧右侧的空格
     * @param value
     * @return
     */
    public static String trim(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return leftTrim(rightTrim(value));
    }
  • 获取字符串的长度
    /**
     * 获取字符串的长度
     * @param value
     * @return
     */
    public static int length(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.length();
    }
  • 在字符串的前端添加字符串
    public static String prependArray(String value, String[] prepends){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        if(prepends == null || prepends.length == 0){
            return value;
        }
        StringJoiner joiner = new StringJoiner("");
        for(String prepend : prepends){
            joiner.add(prepend);
        }
        return joiner.toString() + value;
    }

    /**
     * 在字符串的前端添加字符串
     * @param value
     * @param prepends
     * @return
     */
    public static String prepend(String value, String... prepends){
        return prepend(value, prepends);
    }
  • 去除字符串数组中的字符串
    /**
     * 去除字符串数组中的字符串
     * @param strings
     * @return
     */
    public static String[] removeEmptyStrings(String[] strings){
        if(Objects.isNull(strings)){
            throw new IllegalArgumentException("字符数组不能为空");
        }
        return Arrays.stream(strings).filter(str -> str != null && !str.trim().isEmpty()).toArray(String[]::new);
    }
  • 删除字符串的子串前缀, 默认区分大下写 & 删除字符串的子串后缀
    public static String removeLeft(String value, String prefix, boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE`, NULL_STRING_MSG);
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        if(caseSensitive){
            return value.startsWith(prefix) ? value.substring(prefix.length()) : value;
        }
        return value.toLowerCase().startsWith(prefix.toLowerCase()) ? value.substring(prefix.length()) : value;
    }

    /**
     * 删除字符串的子串前缀, 默认区分大下写 
     * @param value
     * @param prefix
     * @return
     */
    public static String removeLeft(String value, String prefix){
        return removeLeft(value, prefix, true);
    }

    public static String removeRight(String value, String suffix, boolean caseSensitive){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        return endsWith(value, suffix, caseSensitive) ? value.substring(0, value.toLowerCase().lastIndexOf(suffix.toLowerCase(Locale.ROOT))) : value;
    }

    /**
     * 删除字符串的子串后缀
     * @param value
     * @param suffix
     * @return
     */
    public static String removeRight(String value, String suffix){
        return removeRight(value, suffix,true);
    }
  • 删除字符串中所有的非字母的字符 & 删除字符串中所有的空格
    /**
     * 删除字符串中所有的非字母的字符
     * @param value
     * @return
     */
    public static String removeNoWords(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.replaceAll("[^\\w]+", "");
    }

    /**
     * 删除字符串中所有的空格
     * @param value
     * @return
     */
    public static String removeSpaces(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.replaceAll("\\s", "");
    }
  • 反转字符串
    /**
     * 反转字符串
     * @param value
     * @return
     */
    public static String reverse(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return new StringBuilder(value).reverse().toString();
    }
  • 分割字符串为字符串数组,默认以空白分割
    public static String[] words(String value, String delimiter){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.split(delimiter);
    }

    /**
     * 分割字符串为字符串数组,默认以空白分割
     * @param value
     * @return
     */
    public static String[] words(String value){
        return words(value, "\\s+");
    }
  • 随机打乱字符串各位置的值
    /**
     * 随机打乱字符串各位置的值
     * @param value
     * @return
     */
    public static String shuffle(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        String[] chars = chars(value);
        Random random = new Random();

        for(int i = 0; i < chars.length; i++){
            int r = random.nextInt(chars.length);
            String tmp = chars[i];
            chars[i] = chars[r];
            chars[r] = tmp;
        }

        return Arrays.stream(chars).collect(Collectors.joining());
    }
  • 获取begin到end之间的字符串
    /**
     * 获取begin到end之间的字符串
     * @param value
     * @param begin
     * @param end
     * @return
     */
    public static String slice(String value, int begin, int end){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return value.substring(begin, end);
    }
  • 替换字符串中的非法字符
    /**
     * 替换字符串中的非法字符
     * @param value
     * @return
     */
    public static String transliterate(String value){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);

        String res = value;
        Set<Map.Entry<String, List<String>>> entries = Ascii.ascii.entrySet();
        for(Map.Entry<String, List<String>> entry : entries){
            for(String ch : entry.getValue()){
                res = res.replace(ch, entry.getKey());
            }
        }
        return res;
    }
  • 在字符串前后填充子串
    /**
     * 在字符串前后填充子串
     * @param value
     * @param prefix
     * @param suffix
     * @return
     */
    public static String surround(String value, String prefix, String suffix){
        validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG);
        return append(Optional.ofNullable(prefix).orElse(""), value, Optional.ofNullable(suffix).orElse(""));
    }

3.将maven项目安装到本地仓库

点击install,即可将该项目安装到本地仓库。在本地仓库也可以看到我们的jar包,这样以后就可以使用这个简单的str工具库库了,当然以后还可以不断完善扩充工具库。
实现一个简单的字符串工具库_第2张图片
实现一个简单的字符串工具库_第3张图片

小小的使用一把

创建一个demo的maven项目,引入我们的坐标。
实现一个简单的字符串工具库_第4张图片
当然,也可以创建一个sonatype账号,将自己的maven项目上传到maven中央仓库,让别人也能使用自己的maven项目,这个demo远没有达到能上传中央仓库的层度,所以这里就不介绍具体操作了,感兴趣的可以自行搜索一下步骤,很简单的。

你可能感兴趣的:(java,se,开源项目学习,java,maven)