I'm trying to create a string comprised of a single letter, followed by 4 digits e.g. b6789. I'm getting stuck when I try to convert a character, and integer to one String. I can't use toString() because I've overwritten it, and I assume that concatenation is not the best way to approach it? This was my solution, until I realised that valueof() only takes a single parameter. Any suggestions? FYI - I'm using Random, because I will be creating multiples at some point. The rest of my code seemed irrelevant, and hence has been omitted.
Random r = new Random();
Integer numbers = r.nextInt(9000) + 1000;
Character letter = (char)(r.nextInt(26) + 'a');
String strRep = String.valueOf(letter, numbers);
I think they mean for you not to use concatenation with + operator.
Rather than that, there's a class called StringBuilder which will do the trick for you. Just create an empty one, append anything you need on it (takes Objects or primitives as arguments and does all the work for you), and at the end, just call at its "toString()" method, and you'll have your concatenated String.
For example
StringBuilder sb = new StringBuilder();
sb.append("Foo");
sb.append(123);
return sb.toString();
would return the string Foo123
you can use:
Character.toString(char)
which is
String.valueOf(char)
in reality which also works.
or just use
String str = "" + 'a';
as already mentioned but not very efficient as it is
String str = new StringBuilder().append("").append('a').toString();
in reality.
same goes for integer + string or char + int to string. I think your simpliest way would be to use string concatenation
Looks like you want
String.valueOf(letter).concat(numbers.toString());
I want to replace some strings in a String input :
string=string.replace("<h1>","<big><big><big><b>");
string=string.replace("</h1>","</b></big></big></big>");
string=string.replace("<h2>","<big><big>");
string=string.replace("</h2>","</big></big>");
string=string.replace("<h3>","<big>");
string=string.replace("</h3>","</big>");
string=string.replace("<h4>","<b>");
string=string.replace("</h4>","</b>");
string=string.replace("<h5>","<small><b>");
string=string.replace("</h5>","</b><small>");
string=string.replace("<h6>","<small>");
string=string.replace("</h6>","</small>");
As you can see this approach is not the best, because each time I have to search for the portion to replace etc, and Strings are immutable... Also the input is large, which means that some performance issues are to be considered.
Is there any better approach to reduce the complexity of this code ?
Although StringBuilder.replace() is a huge improvement compared to String.replace(), it is still very far from being optimal.
The problem with StringBuilder.replace() is that if the replacement has different length than the replaceable part (applies to our case), a bigger internal char array might have to be allocated, and the content has to be copied, and then the replace will occur (which also involves copying).
Imagine this: You have a text with 10.000 characters. If you want to replace the "XY" substring found at position 1 (2nd character) to "ABC", the implementation has to reallocate a char buffer which is at least larger by 1, has to copy the old content to the new array, and it has to copy 9.997 characters (starting at position 3) to the right by 1 to fit "ABC" into the place of "XY", and finally characters of "ABC" are copied to the starter position 1. This has to be done for every replace! This is slow.
Faster Solution: Building Output On-The-Fly
We can build the output on-the-fly: parts that don't contain replaceable texts can simply be appended to the output, and if we find a replaceable fragment, we append the replacement instead of it. Theoretically it's enough to loop over the input only once to generate the output. Sounds simple, and it's not that hard to implement it.
Implementation:
We will use a Map preloaded with mappings of the replaceable-replacement strings:
Map<String, String> map = new HashMap<>();
map.put("<h1>", "<big><big><big><b>");
map.put("</h1>", "</b></big></big></big>");
map.put("<h2>", "<big><big>");
map.put("</h2>", "</big></big>");
map.put("<h3>", "<big>");
map.put("</h3>", "</big>");
map.put("<h4>", "<b>");
map.put("</h4>", "</b>");
map.put("<h5>", "<small><b>");
map.put("</h5>", "</b></small>");
map.put("<h6>", "<small>");
map.put("</h6>", "</small>");
And using this, here is the replacer code: (more explanation after the code)
public static String replaceTags(String src, Map<String, String> map) {
StringBuilder sb = new StringBuilder(src.length() + src.length() / 2);
for (int pos = 0;;) {
int ltIdx = src.indexOf('<', pos);
if (ltIdx < 0) {
// No more '<', we're done:
sb.append(src, pos, src.length());
return sb.toString();
}
sb.append(src, pos, ltIdx); // Copy chars before '<'
// Check if our hit is replaceable:
boolean mismatch = true;
for (Entry<String, String> e : map.entrySet()) {
String key = e.getKey();
if (src.regionMatches(ltIdx, key, 0, key.length())) {
// Match, append the replacement:
sb.append(e.getValue());
pos = ltIdx + key.length();
mismatch = false;
break;
}
}
if (mismatch) {
sb.append('<');
pos = ltIdx + 1;
}
}
}
Testing it:
String in = "Yo<h1>TITLE</h1><h3>Hi!</h3>Nice day.<h6>Hi back!</h6>End";
System.out.println(in);
System.out.println(replaceTags(in, map));
Output: (wrapped to avoid scroll bar)
Yo<h1>TITLE</h1><h3>Hi!</h3>Nice day.<h6>Hi back!</h6>End
Yo<big><big><big><b>TITLE</b></big></big></big><big>Hi!</big>Nice day.
<small>Hi back!</small>End
This solution is faster than using regular expressions as that involves much overhead, like compiling a Pattern, creating a Matcher etc. and regexp is also much more general. It also creates many temporary objects under the hood which are thrown away after the replace. Here I only use a StringBuilder (plus char array under its hood) and the code iterates over the input String only once. Also this solution is much faster that using StringBuilder.replace() as detailed at the top of this answer.
Notes and Explanation
I initialized the StringBuilder in the replaceTags() method like this:
StringBuilder sb = new StringBuilder(src.length() + src.length() / 2);
So basically I created it with an initial capacity of 150% of the length of the original String. This is because our replacements are longer than the replaceable texts, so if replacing occurs, the output will obviously be longer than the input. Giving a larger initial capacity to StringBuilder will result in no internal char[] reallocation at all (of course the required initial capacity depends on the replaceable-replacement pairs and their frequency/occurrence in the input, but this +50% is a good upper estimation).
I also utilized the fact that all replaceable strings start with a '<' character, so finding the next potential replaceable position becomes blazing-fast:
int ltIdx = src.indexOf('<', pos);
It's just a simple loop and char comparisons inside String, and since it always starts searching from pos (and not from the start of the input), overall the code iterates over the input String only once.
And finally to tell if a replaceable String does occur at the potential position, we use the String.regionMatches() method to check the replaceable stings which is also blazing-fast as all it does is just compares char values in a loop and returns at the very first mismatching character.
And a PLUS:
The question doesn't mention it, but our input is an HTML document. HTML tags are case-insensitive which means the input might contain <H1> instead of <h1>.
To this algorithm this is not a problem. The regionMatches() in the String class has an overload which supports case-insensitive comparison:
boolean regionMatches(boolean ignoreCase, int toffset, String other,
int ooffset, int len);
So if we want to modify our algorithm to also find and replace input tags which are the same but are written using different letter case, all we have to modify is this one line:
if (src.regionMatches(true, ltIdx, key, 0, key.length())) {
Using this modified code, replaceable tags become case-insensitive:
Yo<H1>TITLE</H1><h3>Hi!</h3>Nice day.<H6>Hi back!</H6>End
Yo<big><big><big><b>TITLE</b></big></big></big><big>Hi!</big>Nice day.
<small>Hi back!</small>End
For performance - use StringBuilder.
For convenience you can use Map to store values and replacements.
Map<String, String> map = new HashMap<>();
map.put("<h1>","<big><big><big><b>");
map.put("</h1>","</b></big></big></big>");
map.put("<h2>","<big><big>");
...
StringBuilder builder = new StringBuilder(yourString);
for (String key : map.keySet()) {
replaceAll(builder, key, map.get(key));
}
... To replace all occurences in StringBuilder you can check here:
Replace all occurrences of a String using StringBuilder?
public static void replaceAll(StringBuilder builder, String from, String to)
{
int index = builder.indexOf(from);
while (index != -1)
{
builder.replace(index, index + from.length(), to);
index += to.length(); // Move to the end of the replacement
index = builder.indexOf(from, index);
}
}
Unfortunately StringBuilder doesn't provide a replace(string,string) method, so you might want to consider using Pattern and Matcher in conjunction with StringBuffer:
String input = ...;
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile("</?(h1|h2|...)>");
Matcher m = p.matcher( input );
while( m.find() )
{
String match = m.group();
String replacement = ...; //get replacement for match, e.g. by lookup in a map
m.appendReplacement( sb, replacement );
}
m.appendTail( sb );
You could do something similar with StringBuilder but in that case you'd have to implement appendReplacement etc. yourself.
As for the expression you could also just try and match any html tag (although that might cause problems since regex and arbitrary html don't fit very well) and when the lookup doesn't have any result you just replace the match with itself.
The particular example you provide seems to be HTML or XHTML. Trying to edit HTML or XML using regular expressions is frought with problems. For the kind of editing you seem to be interested in doing you should look at using XSLT. Another possibility is to use SAX, the streaming XML parser, and have your back-end write the edited output on the fly. If the text is actually HTML, you might be better using a tolerant HTML parser, such as JSoup, to build a parsed representation of the document (like the DOM), and manipulate that before outputting it.
StringBuilder is backed by a char array. So, unlike String instances, it is mutable. Thus, you can call indexOf() and replace() on the StringBuilder.
I would do something like this
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (tagEquals(str, i, "h1")) {
sb.append("<big><big><big><b>");
i += 2;
} else (tagEquals(s, i, "/h1")) {
...
} else {
sb.append(str.charAt(i));
}
}
tagEquals is a func which checks a tag name
Use Apache Commons StringUtils.replaceEach.
String[] searches = new String[]{"<h1>", "</h1>", "<h2>", ...};
String[] replacements = new String[]("<big><big><big><b>", "</b></big></big></big>", "<big><big>" ...};
string = StringUtils.replaceEach(string, searches, replacements);
Currently, I am working on a project that requires to delete a char at a set position in a string. Is there a simple way to do this?
Use a StringBuilder, which has the method deleteCharAt(). Then, you can just use stringBuilder.toString() to get your string.
EDIT, here's an example:
public static void main(String[] args) {
String string = "bla*h";
StringBuilder sb = new StringBuilder(string);
sb.deleteCharAt(3);
// Prints out "blah"
System.out.println(sb.toString());
}
Strings are immutable ! But to accomplish your task, you can
Copy the substring from the start of the string to the character that has to be deleted
Copy the substring from the character that has to be deleted to the end of the String.
Append the second String to the first one.
For example, let's say you have to remove the third character:
String input = "Hello, World";
String first = input.substring(0, 3);
String second = input.substring(4);
String result = first + second;
You can convert your string to StringBuilder, which have convinient deletaCharAt method.
String strWithoutChar = new StringBuilder(yourString).deleteCharAt(yourIndex).toString();
But keep in mind, this gives to you ability to remove some boilerplate code, but it takes more memory in compassion to using String#substring method.
The way you would do this is by copying the oldstring into a newstring, being careful to remove the one character, like so:
String newString = oldString.substring(0, index) + oldString.substring(index+1);
Keep in mind that if you are doing this several times, constantly making new strings is rather inefficient.
Whatever is being said here by fellow scholars, I agree to them that it gives the correct answer. But if you are dealing with a production level program where every loophole gets magnified, I would suggest you to not use "Substring" method of string because:
(1). substring method actually leaves the parent string unflagged for garbage collector. Due to this garbage collector cannot clean it up in its process, the heap space gets occupied and unused parent strings still remains to exist in the heap space even when it is\ not in use.
(2). If you deal with a number of string manipulations such as these, it may eventually result in 'Out of Heap Memory' exception which is not desirable at any point in time in the program.
Use char array and its manipulations to achieve what you want :
public static void fn1()
{
String a = "Stack Overflow";
char[] b = a.toCharArray();
j // index position of the character that you want to delete
for(int i=j;i<b.length-1;i++)
{
b[i]=b[i+1];
}
b[b.length-1]='\000'; // '\000' is the null character
System.out.println(new String(b));
}
An alternative is to use the substring method but using concat instead of +
String removeCharAt(String s, int index) {
return s.substring(0, index).concat(s.substring(index + 1));
}
I'm using this for loop to go through my array's individual characters from a string.
for(int i=0;i< array;i++){
I need to print the characters one by one using g.drawString. Therefor I need the character at position [i] in the array to be turned into a string. How do I do this?
You can use :
String.valueOf(yourChar)
So your loop would be:
for(int i=0;i< array;i++){
g.drawString(String.valueOf(yourString.charAt(i));
}
It's just simple: "" + array.charAt(i)
Just do this:
char[] array;
g.drawString(String.valueOf(array[i]));
This is the best practice way:
char[] array;
for (char c : array) {
String s = String.valueOf(c);
// do something with s
}
Something like this
char[] chars = {'a','b','c'};
String[] strings = new String[chars.length];
for (int i = 0; i < chars.length; i++) {
strings[i] = String.valueOf(chars[i]);
}
Usually, the best way to do this is if your source is a String:
str.substring(i, i+1); // If you have a string.
because it avoids unnecessary character buffer copies. Some versions of Java (apparently JDK7u5 and earlier) can then reuse the existing character buffer and this way avoid an extra object creation.
(See: this announcement of the change, indicating that this holds for JDK7u5 and before)
There are two quite obvious alternatives (this one also works if you have your own char[] as data source):
String.valueOf(str.charAt(i)); // If you have a String
String.valueOf(chararray[i]); // If you have a char[]
These will actually create two objects: one String and one char[1].
And then there is the ugly hackling:
"" + str.charAt(i); // If you do do not care about doing things right.
which usually causes the creation of a string buffer, with a single append operation, and the conversion to a string. If you use this code in a hot loop, it may really hurt your applications performance. While the code looks really simple, it supposedly translates to:
StringBuilder temp = new StringBuiler("");
temp.append(str.chatAt(i));
temp.toString();
And this overhead is actually quite useless, given that there are two clean solutions available in the API: converting characters to Strings, and constructing substrings.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
when to use StringBuilder in java
If not which of these pieces of code is better and why
public String backAround(String str) {
int len = str.length();
StringBuilder sb = new StringBuilder(str);
char chEnd = sb.charAt(len-1);
if(len > 0){
sb = sb.append(chEnd);
sb= sb.insert(0,chEnd);
str= sb.toString();
return str;
}else{ return str;}
}
or
public String backAround(String str) {
// Get the last char
String back = str.substring(str.length()-1, str.length());
return back + str + back;
}
If you are just "sticking a few elements together" as in your backAround() method, you may as well just use the + notation. The compiler will convert this into appropriate StringBuilder.append()s for you, so why bother 'spelling things out'.
The idea of explicitly using StringBuilder is that in principle you can hand-optimise how exactly the elements are appended to the string, including setting the initial buffer capacity and ensuring that you don't accidentally create intermediate String objects that are unnecessary in cases where the compiler might not predict these things.
So essentially, explicitly use a StringBuilder when there is slightly more complex logic to deciding what to append to the string. For example, if you are appending things in a loop, or where what is appended depends on various conditions at different points. Another case where you might use StringBuilder is if the string needs to be built up from various methods, for example: you can then pass the StringBuilder into the different methods and ask them to append the various elements.
P.S. I should say that StringBuilder buys you a little more editing power as well (e.g. among other things, you can set its length) and, given the presence of the Appendable interface, you can actually create more generic methods that either append to a StringBuilder or to e.g. a StringWriter. But these are marginal cases, I would submit.
It really depends on what you are trying to do. In your case it seems like your trying to take a string and take the last letter and add it to the front and then add another to the end. For this i would probably do this:
public String manipulate(String string)
{
char c = string.charAt(string.length);
return c + string + c;
}
In this case you didn't have to use a StringBuilder. There are cases where the StringBuilder class is useful. Here are some things that are hard to do with a String that StringBuilder can do:
delete chars at an index
append chars at an index
get the index of a specific sequence
and much much more
if you want to see the documentation for StringBuilder:
String Builder
I hope this helped you out!