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.
Related
String Address[] = mSelectedaddress.split("\\|");
address.setText(
Address[1] + "\n"
+ Address[2] + "\n"
+ Address[3] + "\n"
+ Address[4]);
Actual Output:
Address 1
Address 2
=> Blank line
City
Wanted Output:
Address 1
Address 2
City
If u can see my above code there are some scenario where Address[positon] may return blank text that time how can i remove that line if it is blank.
String adjusted = adress.replaceAll("(?m)^[ \t]*\r?\n", "");
When you build your string, check to see if the string is empty before you add it.
StringBuilder builder = new StringBuilder();
for(int it = 0; i < Address.length; i++) {
if(Address[i] != "")
builder.append(Address[i]);
}
address.setText(builder.toString());
}
The simplest thing I can think of that should do the trick most of the time:
mSelectedaddress.replaceAll("[\\|\\s]+", "|").split("\\|");
This will remove multiple |'s (with or without spaces) in a row. Those are the cause of your empty lines.
Example:
"a|b|c|d|e||g" -> works
"a|b|c|d|e| |g" -> works
"a|b|c|d|e|||g" -> works
I am making an application where I will be fetching tweets and storing them in a database. I will have a column for the complete text of the tweet and another where only the words of the tweet will remain (I need the words to calculate which words were most used later).
How I currently do it is by using 6 different .replaceAll() functions which some of them might be triggered twice. For example I will have a for loop to remove every "hashtag" using replaceAll().
The problem is that I will be editing as many as thousands of tweets that I fetch every few minutes and I think that the way I am doing it will not be too efficient.
What my requirements are in this order (also written in comments down bellow):
Delete all usernames mentioned
Delete all RT (retweets flags)
Delete all hashtags mentioned
Replace all break lines with spaces
Replace all double spaces with single spaces
Delete all special characters except spaces
Here is a Short and Compilable Example:
public class StringTest {
public static void main(String args[]) {
String text = "RT #AshStewart09: Vote for Lady Gaga for \"Best Fans\""
+ " at iHeart Awards\n"
+ "\n"
+ "RT!!\n"
+ "\n"
+ "My vote for #FanArmy goes to #LittleMonsters #iHeartAwards"
+ " htt…";
String[] hashtags = {"#FanArmy", "#LittleMonsters", "#iHeartAwards"};
System.out.println("Before: " + text + "\n");
// Delete all usernames mentioned (may run multiple times)
text = text.replaceAll("#AshStewart09", "");
System.out.println("First Phase: " + text + "\n");
// Delete all RT (retweets flags)
text = text.replaceAll("RT", "");
System.out.println("Second Phase: " + text + "\n");
// Delete all hashtags mentioned
for (String hashtag : hashtags) {
text = text.replaceAll(hashtag, "");
}
System.out.println("Third Phase: " + text + "\n");
// Replace all break lines with spaces
text = text.replaceAll("\n", " ");
System.out.println("Fourth Phase: " + text + "\n");
// Replace all double spaces with single spaces
text = text.replaceAll(" +", " ");
System.out.println("Fifth Phase: " + text + "\n");
// Delete all special characters except spaces
text = text.replaceAll("[^a-zA-Z0-9 ]+", "").trim();
System.out.println("Finaly: " + text);
}
}
Relying on replaceAll is probably the biggest performance killer as it compiles the regex again and again. The use of regexes for everything is probably the second most significant problem.
Assuming all usernames start with #, I'd replace
// Delete all usernames mentioned (may run multiple times)
text = text.replaceAll("#AshStewart09", "");
by a loop copying everything until it founds a #, then checking if the following chars match any of the listed usernames and possibly skipping them. For this lookup you could use a trie. A simpler method would be a replaceAll-like loop for the regex #\w+ together with a HashMap lookup.
// Delete all RT (retweets flags)
text = text.replaceAll("RT", "");
Here,
private static final Pattern RT_PATTERN = Pattern.compile("RT");
is a sure win. All the following parts could be handled similarly. Instead of
// Delete all special characters except spaces
text = text.replaceAll("[^a-zA-Z0-9 ]+", "").trim();
you could use Guava's CharMatcher. The method removeFrom does exactly what you did, but collapseFrom or trimAndCollapseFrom might be better.
According to the now closed question, it all boils down to
tweet = tweet.replaceAll("#\\w+|#\\w+|\\bRT\\b", "")
.replaceAll("\n", " ")
.replaceAll("[^\\p{L}\\p{N} ]+", " ")
.replaceAll(" +", " ")
.trim();
The second line seems to be redundant as the third one does remove \n too. Changing the first line's replacement to " " doesn't change the outcome an allows to aggregate the replacements.
tweet = tweet.replaceAll("#\\w*|#\\w*|\\bRT\\b|[^##\\p{L}\\p{N} ]+", " ")
.replaceAll(" +", " ")
.trim();
I've changed the usernames and hashtags part to eating also lone # or #, so that it doesn't need to be consumed by the special chars part. This is necessary for corrent processing of strings like !#AshStewart09.
For maximum performance, you surely need a precompiled pattern. I'd also re-suggest to use Guava's CharMatcher for the second part. Guava is huge (2 MB I guess), but you surely find more useful things there. So in the end you can get
private static final Pattern PATTERN =
Pattern.compile("#\\w*|#\\w*|\\bRT\\b|[^##\\p{L}\\p{N} ]+");
private static final CharMatcher CHAR_MATCHER = CharMacher.is(" ");
tweet = PATTERN.matcher(tweet).replaceAll(" ");
tweet = CHAR_MATCHER.trimAndCollapseFrom(tweet, " ");
You can inline all of the things that are being replaced with nothing into one call to replace all and everything that is replaced with a space into one call like so (also using a regex to find the hashtags and usernames as this seems easier):
text = text.replaceAll("#\w+|#\w+|RT", "");
text = text.replaceAll("\n| +", " ");
text = text.replaceAll("[^a-zA-Z0-9 ]+", "").trim();
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