Split and join strings 2
import java.awt.FontMetrics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* Globally available utility classes, mostly for string manipulation.
*
* @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
*/
public class StringUtils {
protected static final int DEFAULT_MAX_MESSAGE_WIDTH = 78;
/**
* Returns a list of substrings created by splitting the given string at the
* given delimiter. The return value will be <code>null</code> if the string
* is <code>null</code>, else it will be a non-empty list of strings. If
* <var>delim</var> is <code>null</code> or is not found in the string, the
* list will contain one element: the original string.
* <p>
* This isn't the same thing as using a tokenizer. <var>delim</var> is a
* literal string, not a set of characters any of which may be a delimiter.
*
* @param str
* the string we're splitting
* @param delim
* the delimter string
*/
public static List split(String str, String delim) {
if (str == null)
return null;
ArrayList list = new ArrayList();
if (delim == null) {
list.add(str);
return list;
}
int subStart, afterDelim = 0;
int delimLength = delim.length();
while ((subStart = str.indexOf(delim, afterDelim)) != -1) {
list.add(str.substring(afterDelim, subStart));
afterDelim = subStart + delimLength;
}
if (afterDelim <= str.length())
list.add(str.substring(afterDelim));
return list;
}
/**
* Returns a string consisting of all members of a collection separated by the
* specified string. The <code>toString</code> method of each collection
* member is called to convert it to a string.
*
* @param c
* a collection of objects
* @param joinWith
* the string that will separate each member of the collection
*/
public static String join(Collection c, String joinWith) {
if (c == null)
return "";
StringBuffer buf = new StringBuffer();
boolean first = true;
for (Iterator iter = c.iterator(); iter.hasNext();) {
if (first)
first = false;
else if (joinWith != null)
buf.append(joinWith);
buf.append(iter.next().toString());
}
return buf.toString();
}
/**
* Returns an array of strings, one for each line in the string. Lines end
* with any of cr, lf, or cr lf. A line ending at the end of the string will
* not output a further, empty string.
* <p>
* This code assumes <var>str</var> is not <code>null</code>.
*
* @param str
* the string to split
* @return a non-empty list of strings
*/
public static List splitIntoLines(String str) {
ArrayList strings = new ArrayList();
int len = str.length();
if (len == 0) {
strings.add("");
return strings;
}
int lineStart = 0;
for (int i = 0; i < len; ++i) {
char c = str.charAt(i);
if (c == '\r') {
int newlineLength = 1;
if ((i + 1) < len && str.charAt(i + 1) == '\n')
newlineLength = 2;
strings.add(str.substring(lineStart, i));
lineStart = i + newlineLength;
if (newlineLength == 2) // skip \n next time through loop
++i;
} else if (c == '\n') {
strings.add(str.substring(lineStart, i));
lineStart = i + 1;
}
}
if (lineStart < len)
strings.add(str.substring(lineStart));
return strings;
}
/**
* Appends a string to a string buffer, adding extra newlines so the message
* is not too wide. Max width is not guaranteed; if there is no space in a
* line before <code>DEFAULT_MAX_MESSAGE_WIDTH</code> then the next one
* after it will be used insetead. Each line will be trimmed before and after
* it's added, so some whitespace may be goofed up. This is used for error
* message wrapping, so it's not critical that whitespace be preserved.
* <p>
* TODO Looks for space, not all whitespace. This should probably change.
*
* @param buf
* the string buffer
* @param str
* the string
*/
public static void splitUp(StringBuffer buf, String str) {
splitUp(buf, str, DEFAULT_MAX_MESSAGE_WIDTH);
}
/**
* Appends a string to a string buffer, adding extra newlines so the message
* is not too wide. Max width is not guaranteed; if there is no space in a
* line before <var>maxWidth</var> then the next one after it will be used
* instead. Each line will be trimmed before and after it's added, so some
* whitespace may be goofed up. This is used for error message wrapping, so
* it's not critical that whitespace be preserved.
* <p>
* TODO Looks for space, not all whitespace. This should probably change.
*
* @param buf
* the string buffer
* @param str
* the string
* @param maxWidth
* maximum number of chars in each line
*/
public static void splitUp(StringBuffer buf, String str, int maxWidth) {
if (str == null)
return;
str = str.trim();
while (str.length() >= maxWidth) {
int pos = str.lastIndexOf(' ', maxWidth);
if (pos == -1) { // No spaces before; look for first one after
pos = str.indexOf(' ', maxWidth);
if (pos == -1)
break;
}
buf.append(str.substring(0, pos).trim());
buf.append("\n");
str = str.substring(pos + 1).trim();
}
buf.append(str);
}
}
Related examples in the same category