I am trying to convert a String into an ArrayList. For example, my Struts2 webapp returns this String named row in a format similar to this:
[A, BB, CCC, DDDD,开发者_C百科 1, 0, 1] (something along those lines)
I need to convert them into an ArrayList so I can prepopulate some forms in another JSP page. I hardcoded a method to convert such Strings into list form:
StringBuffer rowBuffer = new StringBuffer(row);
int startIndex = 0;
int endIndex = rowBuffer.indexOf(",") - 1;
rowBuffer.deleteCharAt(rowBuffer.indexOf("["));
rowBuffer.deleteCharAt(rowBuffer.indexOf("]"));
while(startIndex != -1 && endIndex != -1 && startIndex < endIndex)
{
String subString = rowBuffer.substring(startIndex, endIndex);
if(subString.contains(","))
{
rowList.add(" ");
startIndex = endIndex + 1;
endIndex = rowBuffer.indexOf(",", startIndex);
}
else
{
rowList.add(subString);
startIndex = endIndex + 2;
endIndex = rowBuffer.indexOf(",", startIndex + 1);
}
if(endIndex == -1)
{
rowList.add(rowBuffer.substring(startIndex));
break;
}
}
This works fine in cases where all the fields are populated. However, lets say I have a String that looks like this: [A, BB, , , 1, 0, 0] (the 3rd and 4th fields are missing), then I get something that doesn't work (the blank elements don't register correctly, and the size of the list is 6, when it should be 7). Is there a more elegant solution than hardcoding? If not, could someone point me in the right direction on how to handle cases with blank fields? Thanks!
Try this please:
import java.util.regex.*;
// ...
// Working code
rowBuffer.deleteCharAt(rowBuffer.indexOf("["));
rowBuffer.deleteCharAt(rowBuffer.indexOf("]"));
// Create a pattern to match breaks
Pattern p = Pattern.compile("\\s*,\\s*");
// Split input with the pattern
String[] result = p.split(rowBuffer);
rowList = new ArrayList(Arrays.asList(result));
NOTE: this pre-supposes that the strings themselves do not contain commas and are not quoted. If you want to parse real CSV with commas in the fields and quoted values, do NOT use regular expressions and split; and instead use a dedicated state machine CSV parser (here's one example: http://opencsv.sourceforge.net/ - or you can roll your own, like BalusC example here)
Well I changed my code a bit and made it work (it's probably far from the most elegant solution, but it works for me...
StringBuffer rowBuffer = new StringBuffer(row);
int startIndex = 0;
int endIndex = rowBuffer.indexOf(",") - 1;
rowBuffer.deleteCharAt(rowBuffer.indexOf("["));
rowBuffer.deleteCharAt(rowBuffer.indexOf("]"));
while(startIndex != -1 && endIndex != -1 && startIndex < endIndex)
{
String subString = rowBuffer.substring(startIndex, endIndex);
if(subString.contains(","))
{
rowList.add(" ");
startIndex = endIndex - 1;
endIndex = rowBuffer.indexOf(", ", startIndex + 1);
}
else
{
if(subString.equals("1"))
rowList.add("True");
else if(subString.equals("0"))
rowList.add("False");
else
rowList.add(subString);
startIndex = endIndex + 2;
endIndex = rowBuffer.indexOf(",", startIndex + 1);
}
if(endIndex == -1)
{
if(subString.equals("1"))
rowList.add("True");
else if(subString.equals("0"))
rowList.add("False");
break;
}
}
Assuming that the format is as specified by AbstractCollection.toString()
, then you can simply:
- Remove the surrounding brackets (with simple
substring
) - Then
split
on", "
(comma and space) - Wrap the
String[]
into aList<String>
usingArrays.asList
- Use that to populate an
ArrayList<String>
if necessary
- Use that to populate an
Note that this will break if the elements themselves can contain ", "
. For this to work, that string must be a delimiter, and never part of the actual token.
Here's a snippet to illustrate:
String s = "[A, BB, CCC, DDDD, 1, 0, 1]";
String[] parts = s.substring(1, s.length() - 1).split(", ");
List<String> list = new ArrayList(Arrays.asList(parts));
for (String part : list) {
System.out.print("{" + part + "} ");
} // {A} {BB} {CCC} {DDDD} {1} {0} {1}
精彩评论