All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ttzero.excel.util.StringUtil Maven / Gradle / Ivy

/*
 * Copyright (c) 2017, [email protected] All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ttzero.excel.util;

/**
 * 字符串工具类,提供一些简单的静态方法
 *
 * @author guanquan.wang on 2017/9/30.
 */
public class StringUtil {
    private StringUtil() { }

    /**
     * 空字符串
     */
    public final static String EMPTY = "";

    /**
     * 检查字符串是否为空字符串,当字符串{@code s}为{@code null}或{@code String.isEmpty}则返回{@code true}
     *
     * @param s 待检查字符串
     * @return {@code true}当字符串为{@code null}或{@code String.isEmpty}
     */
    public static boolean isEmpty(String s) {
        return s == null || s.isEmpty();
    }

    /**
     * 检查字符串不为空字符串,当字符串{@code s}不为{@code null}且长度大小{@code 0}则返回{@code true}
     *
     * @param s 待检查字符串
     * @return {@code true}当字符串不为{@code null}且长度大小{@code 0}
     */
    public static boolean isNotEmpty(String s) {
        return s != null && s.length() > 0;
    }

    /**
     * 查找字符串在数组中第一次出现的位置,查找是从数组头向尾逐一比较,时间复杂度{@code n}(n为数组长度),
     * 建议只应用于小数组查找,待查找字符串{@code v}可以为{@code null},但数组不能为{@code null}
     *
     * @param array 查找源,不为{@code null}
     * @param v     待查找字符串
     * @return 如果存在则返回字符串在数组中第一次出现的下标否则返回 {@code -1}
     */
    public static int indexOf(String[] array, String v) {
        if (v != null) {
            for (int i = 0; i < array.length; i++) {
                if (v.equals(array[i])) {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < array.length; i++) {
                if (array[i] == null) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 首字母大写,转化是强制的它并不会检查空串以及第二个字符是否为大字,外部最好不要使用
     *
     * 

注意:本方法只适用于范围为{@code [97, 122]}的{@code ASCII}值

* * @param key 待处理字符串 * @return 转为首字母大写后的字符串 */ public static String uppFirstKey(String key) { char first = key.charAt(0); if (first >= 97 && first <= 122) { char[] _v = key.toCharArray(); _v[0] -= 32; return new String(_v); } return key; } /** * 首字母小写,转化是强制的它并不会检查空串,外部最好不要使用 * * @param key 待处理字符串 * @return 转为首字母大写后的字符串 */ public static String lowFirstKey(String key) { char first = key.charAt(0); if (first >= 65 && first <= 90) { char[] _v = key.toCharArray(); _v[0] += 32; return new String(_v); } return key; } /** * 将字符串转为驼峰风格,仅支持将下划线{@code '_'}风格转驼峰风格,内部不检查参数是否为{@code null}请谨慎使用 *
     * 转换前       | 转换后
     * ------------+------------
     * GOODS_NAME  | goodsName
     * NAME        | name
     * goods__name | goodsName
     * _goods__name| _goodsName
     * 
* * @param name 待转换字符串 * @return 驼峰风格字符串 */ public static String toCamelCase(String name) { if (name.indexOf('_') < 0) return name.toLowerCase(); char[] oldValues = name.toLowerCase().toCharArray(); final int len = oldValues.length; int i = 1, idx = i; for (int n = len - 1; i < n; i++) { char c = oldValues[i], cc = oldValues[i + 1]; if (c == '_') { if (cc == '_') continue; i++; oldValues[idx++] = cc >= 'a' && cc <= 'z' ? (char) (cc - 32) : cc; } else { oldValues[idx++] = c; } } if (i < len) oldValues[idx++] = oldValues[i]; return new String(oldValues, 0, idx); } /** * 交换数组中的值,交换是强制的它并不会检查下标的范围,外部最好不要使用 * * @param values 数组 * @param a 指定交换下标 * @param b 指定交换下标 */ public static void swap(String[] values, int a, int b) { String t = values[a]; values[a] = values[b]; values[b] = t; } /** * 检查字符串是否为{@code null}或空白字符 * * @param cs 待检查的字符串 * @return {@code true} 字符串为{@code null}或空白字符 */ public static boolean isBlank(final CharSequence cs) { int strLen; if (cs == null || (strLen = cs.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } /** * 检查字符串不为{@code null}或非空白字符 * * @param cs 待检查的字符串 * @return {@code true} 字符串不为{@code null}或非空白字符 */ public static boolean isNotBlank(final CharSequence cs) { return !isBlank(cs); } /** * 格式化字节大小,将字节大小转为{@code kb,mb,gb}等格式 * * @param size 字节大小 * @return 格式化字符串 */ public static String formatBinarySize(long size) { long kb = 1 << 10, mb = kb << 10, gb = mb << 10; String s; if (size >= gb) s = String.format("%.2fGB", (double) size / gb); else if (size >= mb) s = String.format("%.2fMB", (double) size / mb); else if (size >= kb) s = String.format("%.2fKB", (double) size / kb); else s = String.format("%dB", size); return s.replace(".00", ""); } /** * 毫秒时间转字符串,通常用于格式化某段代码的耗时, 如:1h:3s or 4m:1s * * @param t 毫秒时间 * @return 格式化文本 */ public static String timeToString(long t) { int n = (int) t / 1000; int h = n / 3600, m = (n - h * 3600) / 60, s = n - h * 3600 - m * 60, ms = (int) (t - n * 1000); return (h > 0 ? h + "h" : "") + (m > 0 ? (h > 0 ? ":" : "") + m + "m" : "") + (s > 0 ? (h + m > 0 ? ":" : "") + s + "s" : "") + (ms > 0 ? ((h + m + s > 0 ? ":" : "") + ms + "ms") : (h + m + s > 0 ? "" : "0ms")); } /** * 查找某个字符{@code ch}在字符串{@code str}的位置,与{@link String#indexOf(int, int)}不同之处在于 * 后者从开始位置查找到字符串结尾,而前者需要指定一个结束位置查找范围在{@code fromIndex}到{@code toIndex}之间 * * @param str 字符串源 * @param ch 待查找的字符 * @param fromIndex 起始位置(包含) * @param toIndex 结束位置(不包含) * @return 字符 {@code ch} 在字符串的位置,未找到时返回{@code -1} */ public static int indexOf(String str, int ch, int fromIndex, int toIndex) { final int max = Math.min(str.length(), toIndex); if (fromIndex < 0) { fromIndex = 0; } else if (fromIndex >= max) { // Note: fromIndex might be near -1>>>1. return -1; } final char[] value = str.toCharArray(); if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { // handle most cases here (ch is a BMP code point or a // negative value (invalid code point)) for (int i = fromIndex; i < max; i++) { if (value[i] == ch) { return i; } } return -1; } else { return indexOfSupplementary(value, ch, fromIndex, max); } } /** * UTF-8编码一个字符理论上最多占用3个字节,所以需要逐个比较每个字节,但目前为止UTF-8只使用了最多2个字节来表示世界上所有的文字, * 所以这里比较最多2个字节 */ private static int indexOfSupplementary(char[] value, int ch, int fromIndex, int toIndex) { if (Character.isValidCodePoint(ch)) { final char hi = Character.highSurrogate(ch); final char lo = Character.lowSurrogate(ch); final int max = toIndex - 1; for (int i = fromIndex; i < max; i++) { if (value[i] == hi && value[i + 1] == lo) { return i; } } } return -1; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy