I'm dynamically creating a string
StringBuilder preparedStatement = new StringBuilder();
states.keySet().forEach(key -> preparedStatement
.append(key)
.append(" = ")
.append(":")
.append(key)
.append(" AND "));
I want to remove the last AND at the end of the loop. Is this possible?
Yes. You know how wide the " AND " is, so just use StringBuilder#delete:
preparedStatement.delete(preparedStatement.length() - " AND ".length(),
preparedStatement.length()
);
Or, if you're about to turn it into a String anyway, use StringBuilder#substring:
String result = preparedStatement.substring(0,
preparedStatement.length()
- " AND ".length()
);
Actually I think that StringBuilder does not support deleting in general case. It was designed to build a string.
I reccomend you just not to add " AND " to the builder:
StringBuilder buf = new StringBuilder();
if(someCheck)
buf.add(" AND ");
This is the best choice, because to delete this part, you have to do a string copy.
Related
I want to use a lambda expression instead of a classic for.
String str = "Hello, Maria has 30 USD.";
String[] FORMAT = {"USD", "CAD"};
final String simbol = "$";
// This was the initial implementation.
// for (String s: FORMAT) {
// str = str.replaceAll(s + "\\s", "\\" + FORMAT);
// }
Arrays.stream(FORMAT).forEach(country -> {
str = str.replaceAll(country + "\\s", "\\" + simbol);
});
// and I tried to do like that, but I receiced an error
// "Variable used in lambda expression should be final or effectively final"
// but I don't want the str String to be final
For any string, I want to change the USD or CAD in $ simbol.
How can I changed this code to work ? Thanks in advance!
I see no problem with using a loop for this. That's how I'd likely do it.
You can do it with a stream using reduce:
str = Arrays.stream(FORMAT)
.reduce(
str,
(s, country) -> s.replaceAll(country + "\\s", Matcher.quoteReplacement(simbol)));
Or, easier:
str = str.replaceAll(
Arrays.stream(FORMAT).collect(joining("|", "(", ")")) + "\\s",
Matcher.quoteReplacement(simbol));
Consider using a traditional for loop, since you're changing a global variable:
for(String country: FORMAT) {
str = str.replaceAll(country + "\\s", "\\" + simbol);
}
Using Streams in this example will make things less readable.
I am trying to write to a text document with a specific format. Here's what I have right now.
String line = "";
double totalCost = 0;
Node curr = summary.head.next;
while(curr!=summary.tail)
{
line += [an assortment of strings and variables] +"\r";
totalCost += PRICELIST.get(curr.itemName)*curr.count;
curr = curr.next;
}
write.printf("%s" + "%n", line);
This is what the part adding onto line actually looks like.
"Item's name: " + curr.itemName + ", Cost per item: " + NumberFormat.getCurrencyInstance().format(PRICELIST.get(curr.itemName)) +
", Quantity: " + curr.count + ", Cost: " + NumberFormat.getCurrencyInstance().format(PRICELIST.get(curr.itemName)*curr.count) + "\r";
I've tried that with a newline character too. Before I had it working when the print statement was inside the loop meaning it only wrote one line at a time. I want to do it this way because I will have multiple threads writing to this file and this way any thread will not hold the lock for as long.
If using Java 7 or later you can use System.lineSeparator()
Use System.getProperty("line.separator") instead of "\r"
Cache ir for efficiency though.
First of all don't use
while(..){
result += newString
..
}
inside loop. This is very inefficient especially for long texts because each time you call
result += newString
you are creating new String which needs to copy content of result and append to it newStrint. So the more text you processed so far, the more it has to copy so it becomes slower.
Instead use
StringBuilder sb = new StringBuilder();
while(..){
sb.append(newString);
}
result = sb.toString.
which in your case should be something more like
sb.append("Item's name: ").append(curr.itemName)
.append(", Cost per item: ").append(NumberFormat.getCurrencyInstance().format(PRICELIST.get(curr.itemName)))
.append(", Quantity: ").append(curr.count )
.append(", Cost: ").append(NumberFormat.getCurrencyInstance().format(PRICELIST.get(curr.itemName) * curr.count))
.append(System.lineSeparator());
Also instead of
write.printf("%s" + "%n", line);
you should use simpler version, which is
write.println(line);
which automatically add line separator based on OS.
You can also try to use \n\r in combination. This helped in one of my projects.
I need to insert a space after every given character in a string.
For example "abc.def..."
Needs to become "abc. def. . . "
So in this case the given character is the dot.
My search on google brought no answer to that question
I really should go and get some serious regex knowledge.
EDIT : ----------------------------------------------------------
String test = "0:;1:;";
test.replaceAll( "\\:", ": " );
System.out.println(test);
// output: 0:;1:;
// so didnt do anything
SOLUTION: -------------------------------------------------------
String test = "0:;1:;";
**test =** test.replaceAll( "\\:", ": " );
System.out.println(test);
You could use String.replaceAll():
String input = "abc.def...";
String result = input.replaceAll( "\\.", ". " );
// result will be "abc. def. . . "
Edit:
String test = "0:;1:;";
result = test.replaceAll( ":", ": " );
// result will be "0: ;1: ;" (test is still unmodified)
Edit:
As said in other answers, String.replace() is all you need for this simple substitution. Only if it's a regular expression (like you said in your question), you have to use String.replaceAll().
You can use replace.
text = text.replace(".", ". ");
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace%28java.lang.CharSequence,%20java.lang.CharSequence%29
If you want a simple brute force technique. The following code will do it.
String input = "abc.def...";
StringBuilder output = new StringBuilder();
for(int i = 0; i < input.length; i++){
char c = input.getCharAt(i);
output.append(c);
output.append(" ");
}
return output.toString();
For the purpose of building a database system I am using a simple builder to generate selection query based on user choices. It has a couple of booleans and then it progresses as follows
StringBuilder builder = new StringBuilder();
builder.append("SELECT ");
if(addOpen)
builder.append("Open ");
if(addHigh)
builder.append("High ");
if(addLow)
builder.append("Low ");
if(addSettle)
builder.append("Settle ");
builder.append("FROM " + tableName);
Now, my problem is trivial - I need to include commas but if I include a comma there must be a value coming after it, so I cannot do Open, or Open, Close, etc. Is there a neat solution to this trivial, yet surprisingly hard for me problem?
Are you looking for something like Apache Commons' StringUtils.join() methods? I.e:
Collection<String> selections = Arrays.asList("Open", "Low");
String clause = StringUtils.join(selections, ',');
Then just
String sql = "SELECT " + clause + " FROM " + TableName;
1) the typical case is you know a priori how many items you have. So you just loop "n-1", then don't append a comma to the last item.
2) One possible solution:
ArrayList<string> items = new ArrayList<String>();
if(addOpen);
items.add("Open ");
if(addHigh)
items.add("High ");
if(addLow)
items.add("Low ");
if(addSettle)
items.add("Settle ");
StringBuilder builder = new StringBuilder();
int i=0;
for (i=0; i < items.size() - 1; i++) {
builder.append(items[i] + ",");
}
builder.append(items[i] + "FROM " + tableName);
...
There's a couple of ways. The first, which would be my first choice, is don't build your SQL statement at all, and just don't display the fields.
The second is, build the string, and just remove the last comma.
The third is to put each field name into an array, and loop through the array, not putting the trailing comma on the last element.
There is a common trick: Select always a constant, which you aren't interested in:
builder.append ("SELECT 1 ");
if (addOpen)
builder.append (", Open ");
if addHigh)
builder.append (", High ");
if (addLow)
builder.append (", Low ");
if (addSettle)
builder.append (", Settle ");
builder.append ("FROM " + tableName);
An alternative approach works in the other direction, with trailing commas:
builder.append ("SELECT ");
if (addOpen)
builder.append ("Open, ");
if (addHigh)
builder.append ("High, ");
if (addLow)
builder.append ("Low, ");
if (addSettle)
builder.append ("Settle, ");
builder.append ("1 FROM " + tableName);
The trick I use (in a generic semi-untyped pseudo-code) is:
pad = "" # Empty string
builder = "SELECT ";
if (addOpen)
builder += pad + "Open"; pad = ", ";
if (addHigh)
builder += pad + "High"; pad = ", ";
if (addLow)
builder += pad + "Low"; pad = ", ";
if (addSettle)
builder += pad + "Settle"; pad = ", ";
builder += "FROM " + TableName;
An alternative I've seen is to always include the comma (or comma space) after the terms, but trim the last two characters off the value before adding the FROM clause. Your choice...the 'pad' technique works even if you're doing output and can't undo an append.
In your situation I use a solution similarto that suggested by Ryan Stewart, but I prefer Google Guava instead of Apache Commons. I prefer this library because I feel that Apache libraries are to gigantic and interlinked.
Here below is how I would build your SQL string:
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.List;
public class SqlJoiner {
public String buildSql(
boolean addOpen,
boolean addHigh,
boolean addLow,
boolean addSettle,
String tableName
) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(tableName));
Preconditions.checkArgument(addOpen | addHigh | addLow | addSettle );
final List<String> clauses = Lists.newArrayList();
if (addOpen) clauses.add("Open");
if (addHigh) clauses.add("High");
if (addLow) clauses.add("Low");
if (addSettle) clauses.add("Settle");
StringBuilder builder = new StringBuilder();
builder.append("SELECT ");
builder.append(Joiner.on(',').join(clauses));
builder.append(" FROM " + tableName);
return builder.toString();
}
}
The precondition at the start of the method body are meant to be sure that at least one of the boolean option is always true, and that tableName is not null or empty. Always check for precondition of your code, it will save you lot of trouble when you'll make mistakes using your code in the future!
I have two strings in a java program, which I want to mix in a certain way to form two new strings. To do this I have to pick up some constituent chars from each string and add them to form the new strings. I have a code like this(this.eka and this.toka are the original strings):
String muutettu1 = new String();
String muutettu2 = new String();
muutettu1 += this.toka.charAt(0) + this.toka.charAt(1) + this.eka.substring(2);
muutettu2 += this.eka.charAt(0) + this.eka.charAt(1) + this.toka.substring(2);
System.out.println(muutettu1 + " " + muutettu2);
I'm getting numbers for the .charAt(x) parts, so how do I convert the chars to string?
StringBuilder builder = new StringBuilder();
builder
.append(this.toka.charAt(0))
.append(this.toka.charAt(1))
.append(this.toka.charAt(2))
.append(' ')
.append(this.eka.charAt(0))
.append(this.eka.charAt(1))
.append(this.eka.charAt(2));
System.out.println (builder.toString());
Just use always use substring() instead of charAt()
In this particular case, the values are mutable, consequently, we can use the built in String class method substring() to solve this problem (#see the example below):
Example specific to the OP's use case:
muutettu1 += toka.substring(0,1) + toka.substring(1,2) + eka.substring(2);
muutettu2 += eka.substring(0,1) + eka.substring(1,2) + toka.substring(2);
Concept Example, (i.e Example showing the generalized approach to take when attempting to solve a problem using this concept)
muutettu1 += toka.substring(x,x+1) + toka.substring(y,y+1) + eka.substring(z);
muutettu2 += eka.substring(x,x+1) + eka.substring(y,y+1) + toka.substring(z);
"...Where x,y,z are the variables holding the positions from where to extract."
The obvious conversion method is Character.toString.
A better solution is:
String muutettu1 = toka.substring(0,2) + eka.substring(2);
String muutettu2 = eka.substring(0,2) + toka.substring(2);
You should create a method for this operation as it is redundant.
The string object instatiantiation new String() is unnecessary. When you append something to an empty string the result will be the appended content.
You can also convert an integer into a String representation in two ways: 1) String.valueOf(a) with a denoting an integer 2) Integer.toString(a)
This thing can adding a chars to the end of a string
StringBuilder strBind = new StringBuilder("Abcd");
strBind.append('E');
System.out.println("string = " + str);
//Output => AbcdE
str.append('f');
//Output => AbcdEf