I hava a List<String> that I need to serialize or make a String representation.
For example I have:
myList.add("Bob");
myList.add("account");
myList.add("userId");
The list can contain variable number of items and I need it to be serialized in this form:
\Bob\-\account\-\userId\
I can do a for loop like:
String ss;
for (String s: myList) {
s = "\\" + s + "\\";
ss = s + "-";
}
However there will be a "-" in the tail of the resulting String ss
Or is there a Google Guava function to do this already?
Using Guava:
String s = Joiner.on('-').join(Iterables.transform(list, new Function<String, String>() {
#Override
public String apply(String input) {
return "\\" + input + "\\";
}
});
The straight-forward way to solve this using Guava is the Joiner:
System.out.println("\\" + Joiner.on("\\-\\").join(myList) + "\\");
You can easily use Apaches Commons StringUtils:
String ss = "\\" + StringUtils.join(myList.iterator(), "\\-\\") + "\\";
Firstly, it is recommended to use StringBuilder during such concatenations.
Secondly, you can use Apache Common Lang's StringUtils.join()` method as follows to achieve the same:
ss = "\\" + StringUtils.join(myList.iterator(), "\\-\\") + "\\";
You can fix it by changing your loop like:
String ss = "";
for (String s: myList) {
s = "\\" + s + "\\";
if(ss.equals("")) {
ss = s;
}
else {
ss += " - " + s;
}
}
Perhaps the other solutions is an old fashioned for loop which is based on the List size().
The other thing I would do is use a StringBuffer as it is more efficient than concatenating Strings. Internally when you concatenate a String, the object is destroyed and recreated.
int myListSize = myList.size();
StringBuffer ss = new StringBuffer(4);
for (int i=0; i < myListSize; i++) {
ss.append("\\").append(myList.get(i)).append("\\");
if (i < myListSize - 1) {
ss.append("-");
}
}
Then to output from a StringBuffer:
ss.toString();
Personally I think these for loops (as above) end up being easier to read.
The simplest code for string joining that I know goes like this:
String sep = "", out = "";
for (String s : myList) {
out += sep + '\\' + s + '\\';
sep = "-";
}
Related
I have written the following function which gets rid of characters in a string that can't be represented in iso88591:
public static String convert(String str) {
if (str.length()==0) return str;
str = str.replace("–","-");
str = str.replace("“","\"");
str = str.replace("”","\"");
return new String(str.getBytes(),iso88591charset);
}
My problem is this doesn't have the behavior I require.
When it comes across a character that has no representation it is converted to multiple bytes. I want that character to be simply omitted from the result.
I would also like to somehow not have to have all those replace commands.
I have been researching charsetEnocder. It has methods like:
CharsetEncoder encoder = iso88591charset.newEncoder();
encoder.onMalformedInput(CodingErrorAction.IGNORE);
encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
which seem to be what I want, but I have failed to even write a function that mimics what I already have using charset encoder yet alone get to set those options.
Also I am restricted to Java 6 :(
Update:
I came up with a nasty solution for this, but there must be a better way to do it:
public static String convert(String str) {
if (str.length()==0) return str;
str = str.replace("–","-");
str = str.replace("“","\"");
str = str.replace("”","\"");
String str2 = "";
for (int c=0;c<str.length();c++) {
String cur = (new Character(str.charAt(c))).toString();
if (cur.equals(new String(cur.getBytes(),iso88591charset))) str2 += cur;
}
return new String(str2.getBytes(),iso88591charset);
}
One possibile way could be
// U+2126 - omega sign
// U+2013 - en dash
// U+201c - left double quotation mark
// U+201d - right double quotation mark
String str = "\u2126\u2013\u201c\u201d";
System.out.println("original = " + str);
str = str.replace("–", "-");
str = str.replace("“", "\"");
str = str.replace("”", "\"");
System.out.println("replaced = " + str);
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray()) {
if (c <= '\u00ff') {
sb.append(c);
}
}
System.out.println("stripped = " + sb);
output
original = Ω–“”
replaced = Ω-""
stripped = -""
I need to write some information into the JSON file.
I have written the following function:
public String toJSON() {
StringBuffer sb = new StringBuffer();
sb.append("\"" + MyConstants.VEHICLE_LABEL + "\":");
sb.append("{");
sb.append("\"" + MyConstants.CAPACITY1_LABEL + "\": " + String.valueOf(this.getCapacity(0)) + ",");
sb.append("\"" + MyConstants.CAPACITY2_LABEL + "\": " + String.valueOf(this.getCapacity(1)) + ",");
sb.append("\"" + MyConstants.CAPACITY3_LABEL + "\": " + String.valueOf(this.getCapacity(2)));
sb.append("}");
return sb.toString();
}
However, I want to make this function more flexible. In particular, how should I change this code if the number of capacity units is not fixed (1, 2 or 3)?
I think that there should be a FOOR loop, however I am not sure how to implement it correctly.
Well you could do the append only if this.getCapacity(i) is not empty.
You could do something like this with a for loop
for(int i=0; i < max; i++) {
if(!StringUtils.isEmpty(String.valueOf(this.getCapacity(i)))){
sb.append("\"" + String.format(MyConstants.CAPACITY_LABEL, i) + "\": " + String.valueOf(this.getCapacity(i)) + ",");
}
}
where MyConstants.CAPACITY_LABEL is something like "capacity%d_label"
But, as azurefrog said, I would use a json parser to do this.
You can try the following class that follows the popular builder pattern:
public class JsonVehicleBuilder {
private StringBuilder builder;
/**
* Starts off the builder with the main label
*/
public JsonVehicleBuilder(String mainLabel) {
builder = new StringBuilder();
builder.append("\"").append(mainLabel).append("\":");
builder.append("{");
}
public JsonVehicleBuilder appendSimpleValue(String label, String value) {
builder.append("\"").append(label).append("\":").append(value).append(",");
return this;
}
/**
* Appends the closing bracket and outputs the final JSON
*/
public String build() {
builder.deleteCharAt(builder.lastIndexOf(",")); //remove last comma
builder.append("}");
return builder.toString();
}
}
And then in your main method you would call:
JsonVehicleBuilder jsonVehicleBuilder = new JsonVehicleBuilder(MyConstants.VEHICLE_LABEL);
jsonVehicleBuilder.appendSimpleValue(MyConstants.CAPACITY1_LABEL,String.valueOf(this.getCapacity(0)))
.appendSimpleValue(MyConstants.CAPACITY2_LABEL,String.valueOf(this.getCapacity(1)))
.appendSimpleValue(MyConstants.CAPACITY3_LABEL,String.valueOf(this.getCapacity(2)));
String json = jsonVehicleBuilder.build();
You can then keep chaining the appendSimpleValue method as long as you like.
Following code block works fine in dev mode but when I deploy to server it does not.Could not split the multi line with new line characters?
Basically, Format the multi-line string as "," separated string tokens.
packages:
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.regexp.shared.SplitResult;
public void onSubmitComplete(SubmitCompleteEvent event) {
String plateStr = "";
if(event.getResults() != null){
String uploadStr = event.getResults();
//Log.warn(this.getClass().getName() + " - event.getResults():"+ uploadStr);
RegExp regExp = RegExp.compile("\\r?\\n");
SplitResult sp = regExp.split(uploadStr);
Log.warn(this.getClass().getName() + " - sp.length():"+ sp.length() + ", SplitResult:"+ sp.toString());
for(int i = 0; i < sp.length() ; i++){
Log.warn(this.getClass().getName() + " - PlateLine["+ i+ "] - " + sp.get(i));
if(!sp.get(i).trim().isEmpty()){
RegExp regLine = RegExp.compile(",");
SplitResult spLine = regLine.split(sp.get(i));
for(int j = 0; j < spLine.length(); j++){
if(spLine.get(j) != null && !spLine.get(j).trim().isEmpty()){
plateStr = plateStr + "," + spLine.get(j);
}
}
}
}
//plateStr = Arrays.toString(lines).replace("[","").replace("]", "");
if(!plateStr.trim().isEmpty()){
plateStr = plateStr.substring(1,plateStr.length());
}
Log.warn(this.getClass().getName() + " - PlateString:"+ plateStr);
}
I tried following workaround with java script native query but it also doesn't work.
JsArrayString arrayString = splitString(uploadStr, "\n");
public static final native JsArrayString splitString(String string, String separator) /*-{
return string.split(separator);
}-*/;
REF:
GWT JSNI split method bug
I'm creating a game of hangman, and long story short, is there a shortcut of sorts to put this array of separate strings together into a string other than doing like below?
String after = under[0] + under[1] + under[2] + under[3] + under[4] + under[5] + under[6] + under[7] + under[8] + under[9] + under[10] + under[11] + under[12] + under[13] + under[14] + under[15] + under[16] + under[17] + under[18] + under[19] + under[20] + under[21];
You can do it with a loop, like this:
StringBuilder sb = new StringBuilder();
for (int i = 0 ; i != 22 ; i++) {
sb.append(under[i]);
}
String after = sb.toString();
You can also add strings to an initially empty string, but that's suboptimal, because all the intermediate strings get allocated and released in a loop.
Always use loop to perform repetitive operation like this.
Also, It is advised to use StringBuilder instead of String. String in JAVA is immutable.
StringBuilder sb = new StringBuilder();
int nCount = 22;
for (int iCnt = 0 ; iCnt <= nCount ; iCnt++) {
sb.append(under[iCnt]);
}
String after = sb.toString();
try it:
String after = "";
for (int i=0; i<22; i++)
after += under[i];
This code is not shorter, but is less tedious:
StringBuilder afterBldr = new StringBuilder();
for (String underEl : under) {
afterBldr.append(underEl);
}
String after = afterBldr.toString();
Apache Joiner can be used here.
Joiner.on("").join(names)
If you have access to the Apache Commons library, use the join() method, it's the nicest solution:
String str = StringUtils.join(under, "");
I want to achieve following using Regular expression in Java
String[] paramsToReplace = {"email", "address", "phone"};
//input URL string
String ip = "http://www.google.com?name=bob&email=okATtk.com&address=NYC&phone=007";
//output URL string
String op = "http://www.google.com?name=bob&email=&address=&phone=";
The URL can contain special characters like %
Try this expression: (email=)[^&]+ (replace email with your array elements) and replace with the group: input.replaceAll("("+ paramsToReplace[i] + "=)[^&]+", "$1");
String input = "http://www.google.com?name=bob&email=okATtk.com&address=NYC&phone=007";
String output = input;
for( String param : paramsToReplace ) {
output = output.replaceAll("("+ param + "=)[^&]+", "$1");
}
For the example above. you can use split
String[] temp = ip.split("?name=")[1].split("&")[0];
op = temp[0] + "?name=" + temp[1].split("&")[0] +"&email=&address=&phone=";
Something like this?
private final static String REPLACE_REGEX = "=.+\\&";
ip=ip+"&";
for(String param : paramsToReplace) {
ip = ip.replaceAll(param+REPLACE_REGEX, Matcher.quoteReplacement(param+"=&"));
}
P.S. This is only a concept, i didn't compile this code.
You don't need regular expressions to achieve that:
String op = ip;
for (String param : paramsToReplace) {
int start = op.indexOf("?" + param);
if (start < 0)
start = op.indexOf("&" + param);
if (start < 0)
continue;
int end = op.indexOf("&", start + 1);
if (end < 0)
end = op.length();
op = op.substring(0, start + param.length() + 2) + op.substring(end);
}