Java tutorial
/** * $Id$ * $License$ * * Created on Oct 30, 2007 4:53:05 PM */ package com.insprise.common.lang; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Formatter; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.StringTokenizer; import java.util.regex.Pattern; /** * String utilities. */ @SuppressWarnings({ "unchecked" }) public class StringUtilities { public static final String[] EMPTY_ARRAY = new String[0]; /** Formatter with two decimal points, trail zeros will be omitted. */ public static final DecimalFormat DECIMAL_FORMAT_COMMON = new DecimalFormat("##########.##"); private static String lineSep; /** * the line separator for this OS * @return */ public static String getLineSeparator() { if (lineSep == null) { lineSep = System.getProperty("line.separator"); } return lineSep; } /** * Get the line break; * @param s * @return */ public static String getLineBreak(String s) { Object[] results = indexOfLineBreakAnyOs(s, 0); if (results != null) { return (String) results[1]; } return null; } /** * Finds index of line break (can be '\r', '\n', or '\r\n'). * @param s string to be searched * @param indexStart index to start the search * @return an array of two element index (int) and line break separator (string), or <code>null</code> if not found. */ public static Object[] indexOfLineBreakAnyOs(String s, int indexStart) { // find line break on any OS win/mac/unix for (int b = indexStart; b < s.length(); b++) { if (s.charAt(b) == '\n') { // unix return new Object[] { b, "\n" }; } else if (s.charAt(b) == '\r') { // windows or mac if (b + 1 < s.length() && s.charAt(b + 1) == '\n') { // Windows return new Object[] { b, "\r\n" }; } else { // mac return new Object[] { b, "\r" }; } } } return null; } private static char[] DIGITS_CHINESE = new char[] {'?', '', '', '', '', '', '', '', '', ''}; /** * Convert all occurrences of in the string to . * @param s * @return the string converted. */ public static String convertChineseDigitsToDigits(String s) { if (s == null) { return null; } for (int i = 0; i < DIGITS_CHINESE.length; i++) { s = s.replace(DIGITS_CHINESE[i], (char) ('0' + i)); } return s; } private static Map<Character, Character> CHINESE_CHAR_ENG_MAP; /** * Replaces chinese chars into their ASCII counterparts, '??' returns '("23!)'. * @param s * @return */ public static String replaceChineseCharsWithASCII(String s) { if(CHINESE_CHAR_ENG_MAP == null) { CHINESE_CHAR_ENG_MAP = new HashMap<Character, Character>(); char[] chars_chinese = new char[] {'?', '', '', '', '', '', '', '', '', '', '', '', '?', '', '?', '', '', '`', '', '', '', '^', '', '', '', '', '?', '?', '', '~', '', '', '', '', '', '', '?', '', '', '' }; char[] chars_english = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',', '`', '?', '!', ':', ';', '\'', '`', '"', '.', '^', '.', '\'', '\'', '"', '"', '"', '"', '~', '(', ')', '{', '}', '<', '>', '(', ')', '<', '>' }; for (int i = 0; i < chars_chinese.length; i++) { CHINESE_CHAR_ENG_MAP.put(chars_chinese[i], chars_english[i]); } } if(s == null) { return null; } StringBuilder sb = null; // created only if there is special Chinese char for(int i=0; i < s.length(); i++) { char c = s.charAt(i); if(c > 0xff) { Character eng = CHINESE_CHAR_ENG_MAP.get(c); if(eng == null) { if(sb != null) { sb.append(c); } }else { if(sb == null) { sb = new StringBuilder(); sb.append(s.substring(0, i)); } sb.append(eng); } }else{ if(sb != null) { sb.append(c); } } } return sb == null ? s : sb.toString(); } /** * Returns true if the given string contains ASCII characters only; false otherwise. * @param s * @return */ public static boolean containsAsciiCharsOnly(String s) { for (int i = 0; s != null && i < s.length(); i++) { if (s.charAt(i) > 0x00ff) { return false; } } return true; } /** * Returns true if the given string contains digit numbers only; false otherwise. * @param s * @return */ public static boolean containsDigitsOnly(String s) { for (int i = 0; s != null && i < s.length(); i++) { char c = s.charAt(i); if (c < '0' || c > '9') { return false; } } return true; } private static char[] printableAsciiChars = null; /** * Returns printable ASCII chars (total 126). * @return */ public static char[] getPrintableAsciiChars() { if (printableAsciiChars == null) { StringBuilder sb = new StringBuilder(); sb.append("0123456789"); // 0-9: 10 sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); // A-Z: 26 sb.append("abcdefghijklmnopqrstuvwxyz"); // a-z: 26 // Ref: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 for (int i = 0xC0; i <= 0xFF; i++) { // - : 64 sb.append((char) i); } printableAsciiChars = new char[sb.length()]; for (int i = 0; i < sb.length(); i++) { printableAsciiChars[i] = sb.charAt(i); } } return printableAsciiChars; } /** * Tokenize the given Java identifier into parts that form it. * @param identifier e.g., 'userName' will result ['user', 'Name']. * @return */ public static String[] tokenizeIdentifierIntoArray(String identifier) { StringBuilder sb = new StringBuilder(); boolean lastIsUpper = false; for (int i = 0; i < identifier.length(); i++) { char c = identifier.charAt(i); if (i == 0) { sb.append(c); lastIsUpper = Character.isUpperCase(c); continue; } if (Character.isUpperCase(c)) { if (lastIsUpper) { // HTT // continue of all upper } else { // fileH -> new part. sb.append(";"); } sb.append(c); lastIsUpper = true; } else { sb.append(c); lastIsUpper = false; } } return tokenizeStringIntoArray(sb.toString(), ";"); } /** * Tokenize the given string with the specified delimiter and returns the tokens in an array. * @param str the string to be tokenized. * @param delimiter the delimiter * @return an array containing all the tokens. */ public static String[] tokenizeStringIntoArray(String str, String delimiter) { StringTokenizer st = new StringTokenizer(str, delimiter); String[] tokens = new String[st.countTokens()]; int index = 0; while (st.hasMoreTokens()) { tokens[index++] = st.nextToken().trim(); } return tokens; } /** * Tokenize the given string with the specified delimiter and returns the tokens in a list. * @param str the string to be tokenized. * @param delimiter the delimiter * @return an list containing all the tokens. */ public static List<String> tokenizeStringIntoList(String str, String delimiter) { StringTokenizer st = new StringTokenizer(str, delimiter); List<String> list = new ArrayList<String>(); while (st.hasMoreTokens()) { list.add(st.nextToken().trim()); } return list; } /** * Capitalize the first letter letter to upper case, no other characters will be changed. * @param s the string to be capitalized. * @return the string with first letter upper-cased. */ public static String capitalizeWord(String s) { if (s == null || s.length() == 0) { return s; } char[] chars = s.toCharArray(); chars[0] = Character.toUpperCase(chars[0]); return new String(chars); } /** * Truncates the given string to the specified length if it is longer than that. * @param s * @param length * @return */ public static String truncate(String s, int length) { if (s == null) { return s; } return s.length() > length ? s.substring(0, length) : s; } /** * Abbreviates the given string using ellipses. * @param s the string * @param maxWidth max number of chars to be shown * @return the abbreviated string or <code>null</code> if the given string is <code>null</code>. */ public static String abbreviate(String s, int maxWidth) { if (s == null) { return null; } if (maxWidth < 4) { throw new IllegalArgumentException("Minimum abbreviation width is 4"); } if (s.length() <= maxWidth) { return s; } return s.substring(0, maxWidth - 3) + "..."; } /** * Abbreviates the given string using ellipses on the left side. * @param s the string * @param maxWidth max number of chars to be shown * @return the abbreviated string or <code>null</code> if the given string is <code>null</code>. */ public static String abbreviateLeft(String s, int maxWidth) { if (s == null) { return null; } if (maxWidth < 4) { throw new IllegalArgumentException("Minimum abbreviation width is 4"); } if (s.length() <= maxWidth) { return s; } return "..." + s.substring(3, 3 + maxWidth); } /** * Counts number of occurrences of the given string. * @param sourceString * @param lookFor * @return */ public static int count(String sourceString, String lookFor) { if (sourceString == null || lookFor == null) { return 0; } int count = 0; int cursor = 0; while ((cursor = sourceString.indexOf(lookFor, cursor)) != -1) { cursor += lookFor.length(); ++count; } return count; } private static Hashtable<String, Pattern> compiledPatterns; /** * Performs regex matche for the given text with optional cache facility. * If <code>cacheCompiledPattern</code> is turned on, compiled patterns will be cached and * saves compilation time for subsequent usages of the same pattern; otherwise, this method * is equivalent to {@linkplain String#matches(String)}. * <p>Under normal conditional, the cache should not grow too large. Thus there is no method * available to clear the cache for the sake of simplicity. </p> * @param pattern the regex pattern. * @param text the text to be matched. * @param cacheCompiledPattern whether compiled patterns should be cached? * @return whether the text matches the pattern. */ public static boolean regexMatch(String pattern, String text, boolean cacheCompiledPattern) { if (pattern == null) { return false; } boolean inCache = false; Pattern regPattern = null; if (compiledPatterns != null) { regPattern = compiledPatterns.get(pattern); } if (regPattern != null) { inCache = true; } else { regPattern = Pattern.compile(pattern); } if (cacheCompiledPattern && !inCache) { if (compiledPatterns == null) { compiledPatterns = new Hashtable<String, Pattern>(); } compiledPatterns.put(pattern, regPattern); } return regPattern.matcher(text).matches(); } /** * Tests whether the two arrays are equal, i.e., all items in an array are contained in the other and vice verse. * The orders of items are ignored. * This method may not perform well when the array size is large as it uses linear search. * @param arrayA * @param arrayB * @param ignoreCase should the case sensitivity be ignored? * @return <code>true</code> if they are equal or <code>false</code> otherwise. */ public static boolean equals(String[] arrayA, String[] arrayB, boolean ignoreCase) { if (arrayA == null && arrayB == null) { return false; } if ((arrayA == null && arrayB != null) || (arrayA != null && arrayB == null)) { return false; } // now, both arrayA and arrayB should not be null. if (arrayA.length != arrayB.length) { return false; } int[] bits = new int[arrayA.length]; for (int i = 0; i < arrayB.length; i++) { String b = arrayB[i]; boolean found = false; for (int j = 0; j < arrayA.length; j++) { String a = arrayA[j]; if (equals(b, a, ignoreCase)) { if (bits[j] == 0) { found = true; bits[j] = 1; break; // the inner for loop. } } } if (!found) { return false; } } return true; } /** * Tests whether the given string is in the specified string array. * @param str the string to be searched. * @param strings the string array * @param ignoreCase should the case be ignore during search. * @return <code>true</code> if the given string is in the array or <code>false</code> otherwise. */ public static boolean contains(String string, String[] strings, boolean ignoreCase) { if (strings == null) { if (string == null) { return true; } else { return false; } } else { // array not null. for (String s : strings) { if (string == null) { if (s == null) { return true; } } else { if (ignoreCase) { if (string.equalsIgnoreCase(s)) { return true; } } else { if (string.equals(s)) { return true; } } } } // for each item in the array. return false; } } /** * Wraps a single line of text. * <p>Modified from Jakarta Commons Lang WordUtils.java. Leading spaces on a new line are stripped, while * trailing spaces are not. </p> * @param string the string to be wrapped. * @param wrapLength the length of the column to wrap the string. * @param wrapLongWords <code>true</code> if long words should be broken and wrapped; <code>false</code> otherwise. * @return an array of lines or <code>null</code> if the string is <code>null</code>. */ public static String[] wrap(String string, int wrapLength, boolean wrapLongWords) { if (string == null) { return null; } if (wrapLength < 1) { wrapLength = 1; } int offset = 0; List<String> lines = new ArrayList<String>(); StringBuilder sb = new StringBuilder(); while ((string.length() - offset) > wrapLength) { if (string.charAt(offset) == ' ') { offset++; continue; } int spaceToWrapAt = string.lastIndexOf(' ', wrapLength + offset); if (spaceToWrapAt >= offset) { // normal case. lines.add(string.substring(offset, spaceToWrapAt)); offset = spaceToWrapAt + 1; } else { // really long word. if (wrapLongWords) { // wrap long word one line at a time. lines.add(string.substring(offset, offset + wrapLength)); offset += wrapLength; } else { // do not wrap. spaceToWrapAt = string.indexOf(' ', offset + wrapLength); if (spaceToWrapAt > 0) { lines.add(string.substring(offset, spaceToWrapAt)); offset = spaceToWrapAt + 1; } else { lines.add(string.substring(offset)); offset = string.length(); // finished. } } } } if (offset < string.length()) { // any left over lines.add(string.substring(offset)); } return getStringArray(lines); } /** * Returns a properly formatted string representation of the given table (a list of lists of strings). * <p><code><pre>{@code List<List<Object>> lists = new ArrayList<List<Object>>(); * List<Object> list = new ArrayList<Object>(); * list.add("ID"); * list.add("Name"); * list.add("Remarks"); * lists.add(list); * * list = new ArrayList<Object>(); * list.add("A"); * list.add("Jack"); * list.add("Employee group"); * list.add("8"); * lists.add(list); * * System.out.println(StringUtilities.displayTable(lists, true, 10)); * * [Results] * +----+------+------------+-------+ * | ID | Name | Remarks | Score | * +----+------+------------+-------+ * | A | Jack | Employee | 8 | * | | | group | | * +----+------+------------+-------+}</pre></code> * @param table * @param firstRowHeadRead is the first row the head read? * if set to <code>true</code>, a line separator will be inserted after the first line. * @param maxColumnLength the max. length of a column. If the data is longer, it will be wrapped. * @return a properly formatted string representation of the given table (a list of lists of strings). */ public static String displayTable(List<List<Object>> table, boolean firstRowHeadRead, int maxColumnLength) { List<Integer> lengths = new ArrayList<Integer>(); // first, find column length. for (int r = 0; r < table.size(); r++) { // for each row for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col String s = null; if (table.get(r).get(c) != null) { s = table.get(r).get(c).toString(); } Integer oldLength = null; if (lengths.size() > c) { oldLength = lengths.get(c); } else { lengths.add(null); } if (s != null) { if (oldLength == null) { lengths.set(c, Math.min(s.length(), maxColumnLength)); } else { lengths.set(c, Math.min(maxColumnLength, Math.max(s.length(), oldLength))); } } else if (oldLength == null || oldLength == 0) { lengths.set(c, 0); } } } StringBuilder sb = new StringBuilder("\n"); // always starts with a new line to avoid misplacement. Formatter formatter = new Formatter(sb); // ------ starts print separator line. for (int i = 0; i < lengths.size(); i++) { sb.append("+-"); // margin is 2. int colLength = lengths.get(i); for (int j = 0; j < colLength + 1; j++) { sb.append("-"); } } sb.append("+"); // ------ finishes print separator line. HashMap<Integer, String[]> wraps = new HashMap<Integer, String[]>(); // used to contain wraps. for (int r = 0; r < table.size(); r++) { // for each row int rowHeight = 1; wraps.clear(); for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col int colLength = lengths.get(c); if (c == 0) { sb.append("\n"); // first col. } sb.append(c == 0 && (!firstRowHeadRead || (firstRowHeadRead && r != 0)) ? "> " : "| "); String s = null; if (table.get(r).get(c) != null) { s = table.get(r).get(c).toString(); } if (s == null) { formatter.format("%-" + colLength + "s", ""); } else { if (s.length() > colLength) { String[] wrap = wrap(s, colLength, true); rowHeight = Math.max(rowHeight, wrap.length); wraps.put(c, wrap); formatter.format("%-" + colLength + "s", wrap[0]); } else { formatter.format("%-" + (colLength == 0 ? 1 : colLength) + "s", s); } } sb.append(" "); // margin. if (c == table.get(r).size() - 1) { // last row sb.append("|"); } } for (int k = 1; k < rowHeight; k++) { // rowHeight > 1 for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col int colLength = lengths.get(c); if (c == 0) { sb.append("\n"); // first col. } sb.append("| "); String s = null; String[] wrap = wraps.get(c); if (wrap != null && wrap.length > k) { s = wrap[k]; } if (s == null) { formatter.format("%-" + (colLength == 0 ? 1 : colLength) + "s", ""); } else { formatter.format("%-" + colLength + "s", s); } sb.append(" "); // margin. if (c == table.get(r).size() - 1) { // last row sb.append("|"); } } } // end for // rowHeight > 1. if (firstRowHeadRead && r == 0) { // ------ starts print separator line. sb.append("\n"); for (int i = 0; i < lengths.size(); i++) { sb.append("+-"); // margin is 2. int colLength = lengths.get(i); for (int j = 0; j < colLength + 1; j++) { sb.append("-"); } } sb.append("+"); // ------ finishes print separator line. } } // end for each row // ------ starts print separator line. sb.append("\n"); for (int i = 0; i < lengths.size(); i++) { sb.append("+-"); // margin is 2. int colLength = lengths.get(i); for (int j = 0; j < colLength + 1; j++) { sb.append("-"); } } sb.append("+"); // ends // ------ finishes print separator line. return sb.toString(); } /** * Converts the given list of Strings into a String array. * If the list is <code>null</code>, it returns <code>null</code>. If the list is empty, * it returns an empty array. * @param list the list of strings * @return a String array or <code>null</code> when the list is <code>null</code>. */ public static String[] getStringArray(List<String> list) { if (list == null) { return null; } String[] ss = new String[list.size()]; list.toArray(ss); return ss; } /** * Returns the first non empty string in the given order of the parameters. * @param strings the list of string. * @return the first non empty string in the given order of the parameters or <code>null</code> if all of them are empty. */ public static String getFirstNonEmptyString(String... strings) { for (String s : strings) { if (isNotEmpty(s)) { return s; } } return null; } /** * Returns <code>true</code>if the string is not null and with length greater than 0. * @param s the string to be tested. * @return <code>true</code>if the string is not null and with length greater than 0; <code>false</code> otherwise. */ public static boolean isNotEmpty(String s) { return s != null && s.length() > 0; } /** * Returns <code>true</code> if the string is null or its length is 0. * @param s the string to be tested. * @return <code>true</code> if the string is null or its length is 0, <code>false</code> otherwise. */ public static boolean isEmpty(String s) { return s == null || s.length() == 0; } /** * Returns <code>true</code> if the string is null or its length is 0 or its contains spaces chars only. * @param s the string to be tested. * @return <code>true</code> if the string is null or its length is 0, <code>false</code> otherwise. */ public static boolean isEmptyOrSpace(String s) { return s == null || s.length() == 0 || s.trim().length() == 0; } /** * Compares whether the two string equals. * Returns <ul><li><code>true</code> if both null; * <li><code>false</code> if one of is null; * <li><code>s1.equals(s2)</code> if neither is null; * </ul> * @param s1 * @param s2 * @param ignoreCase should the case sensitivity be ignored? * @return */ public static boolean equals(String s1, String s2, boolean ignoreCase) { if (s1 == null) { if (s2 == null) { return true; } else { return false; } } else { // s1 not null if (s2 == null) { return false; } else { return ignoreCase ? s1.equalsIgnoreCase(s2) : s1.equals(s2); } } } /** * Prints the string representation of the specified collection to the given string builder. * Elements of the collection will be separated by ', '. * @param collection the collection to be printed. * @param sb the string builder for output. */ public static void printCollection(Collection<?> collection, StringBuilder sb) { if (collection == null) { sb.append("null"); return; } boolean first = true; for (Iterator iter = collection.iterator(); iter.hasNext();) { Object object = (Object) iter.next(); if (first) { first = false; } else { sb.append(", "); } sb.append(object); } } /** * Checks whether the given string represents an integer. * Note it will return false if there are spaces before or after digits. * @param str * @return */ public static boolean isInteger(String str) { return isInteger(str, false); } /** * Checks whether the given string represents an integer. * @param str * @param trimFirst true to trim the string first. * @return */ public static boolean isInteger(String str, boolean trimFirst) { if (str == null) { return false; } if (trimFirst) { str = str.trim(); } if (str.length() == 0) { return false; } for (int i = 0; i < str.length(); i++) { if (!(Character.isDigit(str.charAt(i)) || (i == 0 && (str.charAt(i) == '-') || str.charAt(i) == '+'))) { return false; } } return true; } /** * <p>Checks whether the String a valid Java number. (Source: org.apache.commons.lang.math.NumberUtils)</p> * <p>Valid numbers include hexadecimal marked with the <code>0x</code> * qualifier, scientific notation and numbers marked with a type * qualifier (e.g. 123L).</p> * <p><code>Null</code> and empty String will return * <code>false</code>.</p> * @param str the <code>String</code> to check * @return <code>true</code> if the string is a correctly formatted number */ public static boolean isNumber(String str) { if (str == null || str.length() == 0) { return false; } char[] chars = str.toCharArray(); int sz = chars.length; boolean hasExp = false; boolean hasDecPoint = false; boolean allowSigns = false; boolean foundDigit = false; // deal with any possible sign up front int start = (chars[0] == '-') ? 1 : 0; if (sz > start + 1) { if (chars[start] == '0' && chars[start + 1] == 'x') { int i = start + 2; if (i == sz) { return false; // str == "0x" } // checking hex (it can't be anything else) for (; i < chars.length; i++) { if ((chars[i] < '0' || chars[i] > '9') && (chars[i] < 'a' || chars[i] > 'f') && (chars[i] < 'A' || chars[i] > 'F')) { return false; } } return true; } } sz--; // don't want to loop to the last char, check it afterwords // for type qualifiers int i = start; // loop to the next to last char or to the last char if we need another digit to // make a valid number (e.g. chars[0..5] = "1234E") while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) { if (chars[i] >= '0' && chars[i] <= '9') { foundDigit = true; allowSigns = false; } else if (chars[i] == '.') { if (hasDecPoint || hasExp) { // two decimal points or dec in exponent return false; } hasDecPoint = true; } else if (chars[i] == 'e' || chars[i] == 'E') { // we've already taken care of hex. if (hasExp) { // two E's return false; } if (!foundDigit) { return false; } hasExp = true; allowSigns = true; } else if (chars[i] == '+' || chars[i] == '-') { if (!allowSigns) { return false; } allowSigns = false; foundDigit = false; // we need a digit after the E } else { return false; } i++; } if (i < chars.length) { if (chars[i] >= '0' && chars[i] <= '9') { // no type qualifier, OK return true; } if (chars[i] == 'e' || chars[i] == 'E') { // can't have an E at the last byte return false; } if (!allowSigns && (chars[i] == 'd' || chars[i] == 'D' || chars[i] == 'f' || chars[i] == 'F')) { return foundDigit; } if (chars[i] == 'l' || chars[i] == 'L') { // not allowing L with an exponent return foundDigit && !hasExp; } // last character is illegal return false; } // allowSigns is true iff the val ends in 'E' // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass return !allowSigns && foundDigit; } private static Pattern patternEmailAddr = null; /** * Checks whether the given string represents a valid email address. * @param s * @return */ public static boolean isEmailAddr(String s) { if (s == null) { return false; } if (patternEmailAddr == null) { patternEmailAddr = Pattern.compile("[\\w\\.%\\+-]+@[\\w\\.%\\+-]+\\.[A-Za-z]+"); } return patternEmailAddr.matcher(s).matches(); } // ------------ Copied from Commons Language (v2.3) RandomStringUtilities ----------------------------------------- /** * Creates a random string with the given lenght (count) using the set of chars. */ public static String randomString(int count, char[] chars) { return randomString(count, 0, chars.length - 1, true, true, chars); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * * <p>Characters will be chosen from the set of characters whose * ASCII value is between <code>32</code> and <code>126</code> (inclusive).</p> * * @param count the length of random string to create * @return the random string */ public static String randomAscii(int count) { return randomString(count, 32, 127, false, false, null); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * * <p>Characters will be chosen from the set of alphabetic * characters.</p> * * @param count the length of random string to create * @return the random string */ public static String randomAlphabetic(int count) { return randomString(count, 0, 0, true, false, null); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * * <p>Characters will be chosen from the set of alpha-numeric * characters.</p> * * @param count the length of random string to create * @return the random string */ public static String randomAlphanumeric(int count) { return randomString(count, 0, 0, true, true, null); } /** * <p>Creates a random string whose length is the number of characters * specified.</p> * * <p>Characters will be chosen from the set of numeric * characters.</p> * * @param count the length of random string to create * @return the random string */ public static String randomNumeric(int count) { return randomString(count, 0, 0, false, true, null); } /** * <p>Random object used by random method. This has to be not local * to the random method so as to not return the same value in the * same millisecond.</p> */ private static final Random RANDOM = new Random(); /** * <p>Creates a random string based on a variety of options, using * supplied source of randomness.</p> * * <p>If start and end are both <code>0</code>, start and end are set * to <code>' '</code> and <code>'z'</code>, the ASCII printable * characters, will be used, unless letters and numbers are both * <code>false</code>, in which case, start and end are set to * <code>0</code> and <code>Integer.MAX_VALUE</code>. * * <p>If set is not <code>null</code>, characters between start and * end are chosen.</p> * * <p>This method accepts a user-supplied {@link Random} * instance to use as a source of randomness. By seeding a single * {@link Random} instance with a fixed seed and using it for each call, * the same random sequence of strings can be generated repeatedly * and predictably.</p> * * @param count the length of random string to create * @param start the position in set of chars to start at * @param end the position in set of chars to end before * @param letters only allow letters? * @param numbers only allow numbers? * @param chars the set of chars to choose randoms from. * If <code>null</code>, then it will use the set of all chars. * @param random a source of randomness. * @return the random string * @throws ArrayIndexOutOfBoundsException if there are not * <code>(end - start) + 1</code> characters in the set array. * @throws IllegalArgumentException if <code>count</code> < 0. * @since 2.0 */ public static String randomString(int count, int start, int end, boolean letters, boolean numbers, char[] chars) { Random random = RANDOM; // random instance. if (count == 0) { return ""; } else if (count < 0) { throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); } if ((start == 0) && (end == 0)) { end = 'z' + 1; start = ' '; if (!letters && !numbers) { start = 0; end = Integer.MAX_VALUE; } } char[] buffer = new char[count]; int gap = end - start; while (count-- != 0) { char ch; if (chars == null) { ch = (char) (random.nextInt(gap) + start); } else { ch = chars[random.nextInt(gap) + start]; } if ((letters && Character.isLetter(ch)) || (numbers && Character.isDigit(ch)) || (!letters && !numbers)) { if (ch >= 56320 && ch <= 57343) { if (count == 0) { count++; } else { // low surrogate, insert high surrogate after putting it in buffer[count] = ch; count--; buffer[count] = (char) (55296 + random.nextInt(128)); } } else if (ch >= 55296 && ch <= 56191) { if (count == 0) { count++; } else { // high surrogate, insert low surrogate before putting it in buffer[count] = (char) (56320 + random.nextInt(128)); count--; buffer[count] = ch; } } else if (ch >= 56192 && ch <= 56319) { // private high surrogate, no effing clue, so skip it count++; } else { buffer[count] = ch; } } else { count++; } } return new String(buffer); } /** * Remove all spaces in a word * @param word * @return parsed word */ public static String removeWordSpace(String word) { StringBuilder sb = new StringBuilder(""); int len = word.length(); for (int i = 0; i < len; i++) { Character c = word.charAt(i); if (!Character.isSpaceChar(c)) { sb.append(c); } } return sb.toString(); } }