Is there a way in Java to create a string with a specified number of a specified character? In my case, I would need to create a string with ten spaces. My current code is:
final StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
outputBuffer.append(" ");
}
return outputBuffer.toString();
Is there a better way to accomplish the same thing? In particular, I'd like something that is fast (in terms of execution).
Likely the shortest code using the String API, exclusively:
String space10 = new String(new char[10]).replace('\0', ' ');
System.out.println("[" + space10 + "]");
// prints "[ ]"
As a method, without directly instantiating char:
import java.nio.CharBuffer;
/**
* Creates a string of spaces that is 'spaces' spaces long.
*
* #param spaces The number of spaces to add to the string.
*/
public String spaces( int spaces ) {
return CharBuffer.allocate( spaces ).toString().replace( '\0', ' ' );
}
Invoke using:
System.out.printf( "[%s]%n", spaces( 10 ) );
I highly suggest not to write the loop by hand.
You will do that over and over again during the course of your programming career.
People reading your code - that includes you - always have to invest time, even if it are just some seconds, to digest the meaning of the loop.
Instead reuse one of the available libraries providing code that does just that like StringUtils.repeatfrom Apache Commons Lang:
StringUtils.repeat(' ', length);
That way you also do not have to bother about performance, thus all the gory details of StringBuilder, Compiler optimisations etc. are hidden.
If the function would turn out as slow it would be a bug of the library.
With Java 11 it becomes even easier:
" ".repeat(length);
Hmm now that I think about it, maybe Arrays.fill:
char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);
Of course, I assume that the fill method does the same thing as your code, so it will probably perform about the same, but at least this is fewer lines.
since Java 11:
" ".repeat(10);
since Java 8:
generate(() -> " ").limit(10).collect(joining());
where:
import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;
The for loop will be optimized by the compiler. In such cases like yours you don't need to care about optimization on your own. Trust the compiler.
BTW, if there is a way to create a string with n space characters, than it's coded the same way like you just did.
In Java 8 you can use String.join:
String.join("", Collections.nCopies(n, s));
If you want only spaces, then how about:
String spaces = (n==0)?"":String.format("%"+n+"s", "");
which will result in abs(n) spaces;
Since Java 11 you can simply use String.repeat(count) to solve your problem.
Returns a string whose value is the concatenation of this string repeated count times.
If this string is empty or count is zero then the empty string is returned.
So instead of a loop your code would just look like this:
" ".repeat(length);
I think this is the less code it's possible, it uses Guava Joiner class:
Joiner.on("").join(Collections.nCopies(10, " "));
You can use standard String.format function for generate N spaces.
For example:
String.format("%5c", ' ');
Makes a string with 5 spaces.
or
int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');
Makes a string of 15 spacebars.
If you want another symbol to repeat, you must replace spaces with your desired symbol:
int count = 7;
char mySymbol = '#';
System.out.println(String.format("%" + count + "c", ' ').replaceAll("\\ ", "\\" + mySymbol));
Output:
#######
My contribution based on the algorithm for fast exponentiation.
/**
* Repeats the given {#link String} n times.
*
* #param str
* the {#link String} to repeat.
* #param n
* the repetition count.
* #throws IllegalArgumentException
* when the given repetition count is smaller than zero.
* #return the given {#link String} repeated n times.
*/
public static String repeat(String str, int n) {
if (n < 0)
throw new IllegalArgumentException(
"the given repetition count is smaller than zero!");
else if (n == 0)
return "";
else if (n == 1)
return str;
else if (n % 2 == 0) {
String s = repeat(str, n / 2);
return s.concat(s);
} else
return str.concat(repeat(str, n - 1));
}
I tested the algorithm against two other approaches:
Regular for loop using String.concat() to concatenate string
Regular for loop using a StringBuilder
Test code (concatenation using a for loop and String.concat() becomes to slow for large n, so I left it out after the 5th iteration).
/**
* Test the string concatenation operation.
*
* #param args
*/
public static void main(String[] args) {
long startTime;
String str = " ";
int n = 1;
for (int j = 0; j < 9; ++j) {
n *= 10;
System.out.format("Performing test with n=%d\n", n);
startTime = System.currentTimeMillis();
StringUtil.repeat(str, n);
System.out
.format("\tStringUtil.repeat() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
if (j <5) {
startTime = System.currentTimeMillis();
String string = "";
for (int i = 0; i < n; ++i)
string = string.concat(str);
System.out
.format("\tString.concat() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
} else
System.out
.format("\tString.concat() concatenation performed in x milliseconds\n");
startTime = System.currentTimeMillis();
StringBuilder b = new StringBuilder();
for (int i = 0; i < n; ++i)
b.append(str);
b.toString();
System.out
.format("\tStringBuilder.append() concatenation performed in %d milliseconds\n",
System.currentTimeMillis() - startTime);
}
}
Results:
Performing test with n=10
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 0 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=100
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1 milliseconds
StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=1000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=10000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 43 milliseconds
StringBuilder.append() concatenation performed in 5 milliseconds
Performing test with n=100000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in 1579 milliseconds
StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=1000000
StringUtil.repeat() concatenation performed in 0 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 10 milliseconds
Performing test with n=10000000
StringUtil.repeat() concatenation performed in 7 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 112 milliseconds
Performing test with n=100000000
StringUtil.repeat() concatenation performed in 80 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 1107 milliseconds
Performing test with n=1000000000
StringUtil.repeat() concatenation performed in 1372 milliseconds
String.concat() concatenation performed in x milliseconds
StringBuilder.append() concatenation performed in 12125 milliseconds
Conclusion:
For large n - use the recursive approach
For small n - for loop has sufficient speed
How about this?
char[] bytes = new char[length];
Arrays.fill(bytes, ' ');
String str = new String(bytes);
Considering we have:
String c = "c"; // character to repeat, for empty it would be " ";
int n = 4; // number of times to repeat
String EMPTY_STRING = ""; // empty string (can be put in utility class)
Java 8 (Using Stream)
String resultOne = IntStream.range(0,n)
.mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc
Java 8 (Using nCopies)
String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
RandomStringUtils has a provision to create a string from given input size.
Cant comment on the speed, but its a one liner.
RandomStringUtils.random(5,"\t");
creates an output
\t\t\t\t\t
preferable if you dont want to see \0 in your code.
Use StringUtils:
StringUtils.repeat(' ', 10)
The shortest solution with Guava:
Strings.repeat(" ", len)
Via Simple way to repeat a String in java.
This worked out for me without using any external libraries in Java 8
String sampleText = "test"
int n = 3;
String output = String.join("", Collections.nCopies(n, sampleText));
System.out.println(output);
And the output is
testtesttest
int c = 10;
String spaces = String.format("%" +c+ "c", ' ');
this will solve your problem.
In most cases you only need Strings upto a certains length, say 100 spaces. You could prepare an array of Strings where the index number is equal to the size of the space-filled string and lookup the string, if the required length is within the limits or create it on demand if it's outside the boundary.
For good performance, combine answers from aznilamir and from FrustratedWithFormsDesigner
private static final String BLANKS = " ";
private static String getBlankLine( int length )
{
if( length <= BLANKS.length() )
{
return BLANKS.substring( 0, length );
}
else
{
char[] array = new char[ length ];
Arrays.fill( array, ' ' );
return new String( array );
}
}
Adjust size of BLANKS depending on your requirements. My specific BLANKS string is about 200 characters length.
Just replace your StringBuffer with a StringBuilder. Hard to beat that.
If your length is a big number, you might implement some more efficient
(but more clumsy) self-appendding, duplicating the length in each iteration:
public static String dummyString(char c, int len) {
if( len < 1 ) return "";
StringBuilder sb = new StringBuilder(len).append(c);
int remnant = len - sb.length();
while(remnant > 0) {
if( remnant >= sb.length() ) sb.append(sb);
else sb.append(sb.subSequence(0, remnant));
remnant = len - sb.length();
}
return sb.toString();
}
Also, you might try the Arrays.fill() aproach (FrustratedWithFormsDesigner's answer).
You can replace StringBuffer with StringBuilder ( the latter is not synchronized, may be a faster in a single thread app )
And you can create the StringBuilder instance once, instead of creating it each time you need it.
Something like this:
class BuildString {
private final StringBuilder builder = new StringBuilder();
public String stringOf( char c , int times ) {
for( int i = 0 ; i < times ; i++ ) {
builder.append( c );
}
String result = builder.toString();
builder.delete( 0 , builder.length() -1 );
return result;
}
}
And use it like this:
BuildString createA = new BuildString();
String empty = createA.stringOf( ' ', 10 );
If you hold your createA as a instance variable, you may save time creating instances.
This is not thread safe, if you have multi threads, each thread should have its own copy.
Have a method like this. This appends required spaces at the end of the given String to make a given String to length of specific length.
public static String fillSpaces (String str) {
// the spaces string should contain spaces exceeding the max needed
String spaces = " ";
return str + spaces.substring(str.length());
}
Want String to be of fixed size, so you either pad or truncate, for tabulating data...
class Playground {
private static String fixStrSize(String s, int n) {
return String.format("%-" + n + "s", String.format("%." + n +"s", s));
}
public static void main(String[ ] args) {
System.out.println("|"+fixStrSize("Hell",8)+"|");
System.out.println("|"+fixStrSize("Hells Bells Java Smells",8)+"|");
}
}
|Hell |
|Hells Be|
Excellent reference here.
A simple method like below can also be used
public static String padString(String str, int leng,char chr) {
for (int i = str.length(); i <= leng; i++)
str += chr;
return str;
}
how about this?
public String fillSpaces(int len) {
/* the spaces string should contain spaces exceeding the max needed */
String spaces = " ";
return spaces.substring(0,len);
}
EDIT: I've written a simple code to test the concept and here what i found.
Method 1: adding single space in a loop:
public String execLoopSingleSpace(int len){
StringBuilder sb = new StringBuilder();
for(int i=0; i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Method 2: append 100 spaces and loop, then substring:
public String execLoopHundredSpaces(int len){
StringBuilder sb = new StringBuilder(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ");
for (int i=0; i < len/100 ; i++) {
sb.append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ")
.append(" ").append(" ").append(" ");
}
return sb.toString().substring(0,len);
}
The result I get creating 12,345,678 spaces:
C:\docs\Projects> java FillSpace 12345678
method 1: append single spaces for 12345678 times. Time taken is **234ms**. Length of String is 12345678
method 2: append 100 spaces for 123456 times. Time taken is **141ms**. Length of String is 12345678
Process java exited with code 0
and for 10,000,000 spaces:
C:\docs\Projects> java FillSpace 10000000
method 1: append single spaces for 10000000 times. Time taken is **157ms**. Length of String is 10000000
method 2: append 100 spaces for 100000 times. Time taken is **109ms**. Length of String is 10000000
Process java exited with code 0
combining direct allocation and iteration always takes less time, on average 60ms less when creating huge spaces. For smaller sizes, both results are negligible.
But please continue to comment :-)
I know of no built-in method for what you're asking about. However, for a small fixed length like 10, your method should be plenty fast.
Related
Below Java code produces the valid output but it takes more time to execute. Code works fine in eclipse, but it do not work in an online compiler like hackerrank or hackerearth since it takes more time for execution.Someone help me to find the solution for my time complexity problem.
I have tried to find the solution of the problem but i wasn't able to fix the performance by reducing the time..
Scanner scan = new Scanner(System. in );
String s = "aab";
String s1 = "";
String s2 = "";
int n1 = 0;
int length = 0;
long n = 882787;
long count = 0;
while (s1.length() < n) {
s1 = s1 + s;
}
if (s1.length() > n) {
count = s1.length() - n;
n1 = (int) count;
}
for (int i = 0; i < s1.length() - n1; i++) {
if (s1.charAt(i) == 'a') {
length += 1;
}
}
System.out.println(length);
Explanation of the above program:
I have a string s,in lowercase English letters that .I have repeat the string for n times and I store it in the new string.
I have to find the number of occurrences of 'a' in my new string
How do i actually reduce the time complexity for the above program
Thanks in advance
I would use a regular expression to create a String based on the initial input consisting of only letter 'a'(s). Take the length of that String and multiply it by n. That is one line that looks like
System.out.println(s.replaceAll("[^a]+", "").length() * n);
You are going to add s to the string n/s.length() times, call this N:
int N = n / s.length();
Each time you add s to the string you are going to append the number of As in s:
int a = 0;
for (int i = 0; i < s.length(); ++i) {
a += s.charAt(i) == 'a' ? 1 : 0;
}
// Or int a = s.replaceAll("[^a]", "").length();
So multiple these together:
int length = a * N;
String is immutable. Modification of a string is in fact create a new String object and put both old and new String into Java String constant poom
If you don't want to change your algorithm, I'd suggest to use StringBuilder to improve the speed of the execution. Note that StringBuilder is not thread safe
String s="aab";
int n1 = 0;
StringBuilder sb1 = new StringBuilder();
int length=0;
long n=882787;
long count=0;
while(sb1.length() < n) {
sb1.append(s);
}
if(sb1.length()>n) {
count =sb1.length()-n;
n1=(int)count;
}
for(int i=0;i<sb1.length()- n1;i++) {
if(sb1.charAt(i)=='a') {
length+=1;
}
}
System.out.println(length);
From here
When to use which one :
If a string is going to remain constant throughout the program, then
use String class object because a String object is immutable. If a
string can change (example: lots of logic and operations in the
construction of the string) and will only be accessed from a single
thread, using a StringBuilder is good enough. If a string can change,
and will be accessed from multiple threads, use a StringBuffer because
StringBuffer is synchronous so you have thread-safety.
I see multiple possible optimizations:
a) One pattern that is not that good is creating lots of Strings through repeated string concatenation. Each "s1 = s1 + s;" creates a new instance of String which will be obsolet the next time the command runs (It increases the load, because the String instances will be additional work for the Garbage Collector).
b) Generally: If you find, that your algorithm takes too long, then you should think about a complete new way to solve the issue. So a different solution could be:
- You know the length you want to have (n) and the length of the small string (s1) that you use to create the big string. So you can calculate: How often will the small string be inside the target string? How many characters are left?
==> You can simply check the small string for the character you are looking for. That multiplied by the number how often the small string will be inside the big string is the first result that you get.
==> Now you need to check the substring of the small string that are missing.
Example: n=10, s1="aab", Looking for "a":
So first we check how often the s1 will fit into a new string of n Characters n/length(s1) => 3
So we check how often the "a" is inside "aab" -> 2
First result is 3*2 = 6
But we checked for 3*3 = 9 characters so far, but we want 10 characters. So we need to check n % length(s1) = 1 character of s1 and in this substring ("a"), wie have 1 a, so we have to add 1.
So the result is 7 which we got without building a big string (which is not required at all!)
Just check how many times the char occurs in the original and multiple it by n. Here's a simple way to do so without even using regex:
// take these as function input or w/e
String s = "aab";
String find = "a";
long n = 882787;
int count = s.length() - s.replaceAll(find, "").length();
System.out.println(count * n);
I am trying to concatenate strings in Java. Why isn't this working?
public class StackOverflowTest {
public static void main(String args[]) {
int theNumber = 42;
System.out.println("Your number is " . theNumber . "!");
}
}
You can concatenate Strings using the + operator:
System.out.println("Your number is " + theNumber + "!");
theNumber is implicitly converted to the String "42".
The concatenation operator in java is +, not .
Read this (including all subsections) before you start. Try to stop thinking the php way ;)
To broaden your view on using strings in Java - the + operator for strings is actually transformed (by the compiler) into something similar to:
new StringBuilder().append("firstString").append("secondString").toString()
There are two basic answers to this question:
[simple] Use the + operator (string concatenation). "your number is" + theNumber + "!" (as noted elsewhere)
[less simple]: Use StringBuilder (or StringBuffer).
StringBuilder value;
value.append("your number is");
value.append(theNumber);
value.append("!");
value.toString();
I recommend against stacking operations like this:
new StringBuilder().append("I").append("like to write").append("confusing code");
Edit: starting in java 5 the string concatenation operator is translated into StringBuilder calls by the compiler. Because of this, both methods above are equal.
Note: Spaceisavaluablecommodity,asthissentancedemonstrates.
Caveat: Example 1 below generates multiple StringBuilder instances and is less efficient than example 2 below
Example 1
String Blam = one + two;
Blam += three + four;
Blam += five + six;
Example 2
String Blam = one + two + three + four + five + six;
Out of the box you have 3 ways to inject the value of a variable into a String as you try to achieve:
1. The simplest way
You can simply use the operator + between a String and any object or primitive type, it will automatically concatenate the String and
In case of an object, the value of String.valueOf(obj) corresponding to the String "null" if obj is null otherwise the value of obj.toString().
In case of a primitive type, the equivalent of String.valueOf(<primitive-type>).
Example with a non null object:
Integer theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is 42!
Example with a null object:
Integer theNumber = null;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is null!
Example with a primitive type:
int theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
Output:
Your number is 42!
2. The explicit way and potentially the most efficient one
You can use StringBuilder (or StringBuffer the thread-safe outdated counterpart) to build your String using the append methods.
Example:
int theNumber = 42;
StringBuilder buffer = new StringBuilder()
.append("Your number is ").append(theNumber).append('!');
System.out.println(buffer.toString()); // or simply System.out.println(buffer)
Output:
Your number is 42!
Behind the scene, this is actually how recent java compilers convert all the String concatenations done with the operator +, the only difference with the previous way is that you have the full control.
Indeed, the compilers will use the default constructor so the default capacity (16) as they have no idea what would be the final length of the String to build, which means that if the final length is greater than 16, the capacity will be necessarily extended which has price in term of performances.
So if you know in advance that the size of your final String will be greater than 16, it will be much more efficient to use this approach to provide a better initial capacity. For instance, in our example we create a String whose length is greater than 16, so for better performances it should be rewritten as next:
Example optimized :
int theNumber = 42;
StringBuilder buffer = new StringBuilder(18)
.append("Your number is ").append(theNumber).append('!');
System.out.println(buffer)
Output:
Your number is 42!
3. The most readable way
You can use the methods String.format(locale, format, args) or String.format(format, args) that both rely on a Formatter to build your String. This allows you to specify the format of your final String by using place holders that will be replaced by the value of the arguments.
Example:
int theNumber = 42;
System.out.println(String.format("Your number is %d!", theNumber));
// Or if we need to print only we can use printf
System.out.printf("Your number is still %d with printf!%n", theNumber);
Output:
Your number is 42!
Your number is still 42 with printf!
The most interesting aspect with this approach is the fact that we have a clear idea of what will be the final String because it is much more easy to read so it is much more easy to maintain.
The java 8 way:
StringJoiner sj1 = new StringJoiner(", ");
String joined = sj1.add("one").add("two").toString();
// one, two
System.out.println(joined);
StringJoiner sj2 = new StringJoiner(", ","{", "}");
String joined2 = sj2.add("Jake").add("John").add("Carl").toString();
// {Jake, John, Carl}
System.out.println(joined2);
You must be a PHP programmer.
Use a + sign.
System.out.println("Your number is " + theNumber + "!");
"+" instead of "."
Use + for string concatenation.
"Your number is " + theNumber + "!"
This should work
public class StackOverflowTest
{
public static void main(String args[])
{
int theNumber = 42;
System.out.println("Your number is " + theNumber + "!");
}
}
For exact concatenation operation of two string please use:
file_names = file_names.concat(file_names1);
In your case use + instead of .
For better performance use str1.concat(str2) where str1 and str2 are string variables.
String.join( delimiter , stringA , stringB , … )
As of Java 8 and later, we can use String.join.
Caveat: You must pass all String or CharSequence objects. So your int variable 42 does not work directly. One alternative is using an object rather than primitive, and then calling toString.
Integer theNumber = 42;
String output =
String // `String` class in Java 8 and later gained the new `join` method.
.join( // Static method on the `String` class.
"" , // Delimiter.
"Your number is " , theNumber.toString() , "!" ) ; // A series of `String` or `CharSequence` objects that you want to join.
) // Returns a `String` object of all the objects joined together separated by the delimiter.
;
Dump to console.
System.out.println( output ) ;
See this code run live at IdeOne.com.
In java concatenate symbol is "+".
If you are trying to concatenate two or three strings while using jdbc then use this:
String u = t1.getString();
String v = t2.getString();
String w = t3.getString();
String X = u + "" + v + "" + w;
st.setString(1, X);
Here "" is used for space only.
In Java, the concatenation symbol is "+", not ".".
"+" not "."
But be careful with String concatenation. Here's a link introducing some thoughts from IBM DeveloperWorks.
You can concatenate Strings using the + operator:
String a="hello ";
String b="world.";
System.out.println(a+b);
Output:
hello world.
That's it
So from the able answer's you might have got the answer for why your snippet is not working. Now I'll add my suggestions on how to do it effectively. This article is a good place where the author speaks about different way to concatenate the string and also given the time comparison results between various results.
Different ways by which Strings could be concatenated in Java
By using + operator (20 + "")
By using concat method in String class
Using StringBuffer
By using StringBuilder
Method 1:
This is a non-recommended way of doing. Why? When you use it with integers and characters you should be explicitly very conscious of transforming the integer to toString() before appending the string or else it would treat the characters to ASCI int's and would perform addition on the top.
String temp = "" + 200 + 'B';
//This is translated internally into,
new StringBuilder().append( "" ).append( 200 ).append('B').toString();
Method 2:
This is the inner concat method's implementation
public String concat(String str) {
int olen = str.length();
if (olen == 0) {
return this;
}
if (coder() == str.coder()) {
byte[] val = this.value;
byte[] oval = str.value;
int len = val.length + oval.length;
byte[] buf = Arrays.copyOf(val, len);
System.arraycopy(oval, 0, buf, val.length, oval.length);
return new String(buf, coder);
}
int len = length();
byte[] buf = StringUTF16.newBytesFor(len + olen);
getBytes(buf, 0, UTF16);
str.getBytes(buf, len, UTF16);
return new String(buf, UTF16);
}
This creates a new buffer each time and copies the old content to the newly allocated buffer. So, this is would be too slow when you do it on more Strings.
Method 3:
This is thread safe and comparatively fast compared to (1) and (2). This uses StringBuilder internally and when it allocates new memory for the buffer (say it's current size is 10) it would increment it's 2*size + 2 (which is 22). So when the array becomes bigger and bigger this would really perform better as it need not allocate buffer size each and every time for every append call.
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = value.length >> coder;
int newCapacity = (oldCapacity << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
private int hugeCapacity(int minCapacity) {
int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
int UNSAFE_BOUND = Integer.MAX_VALUE >> coder;
if (UNSAFE_BOUND - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > SAFE_BOUND)
? minCapacity : SAFE_BOUND;
}
Method 4
StringBuilder would be the fastest one for String concatenation since it's not thread safe. Unless you are very sure that your class which uses this is single ton I would highly recommend not to use this one.
In short, use StringBuffer until you are not sure that your code could be used by multiple threads. If you are damn sure, that your class is singleton then go ahead with StringBuilder for concatenation.
First method: You could use "+" sign for concatenating strings, but this always happens in print.
Another way: The String class includes a method for concatenating two strings: string1.concat(string2);
import com.google.common.base.Joiner;
String delimiter = "";
Joiner.on(delimiter).join(Lists.newArrayList("Your number is ", 47, "!"));
This may be overkill to answer the op's question, but it is good to know about for more complex join operations. This stackoverflow question ranks highly in general google searches in this area, so good to know.
you can use stringbuffer, stringbuilder, and as everyone before me mentioned, "+". I'm not sure how fast "+" is (I think it is the fastest for shorter strings), but for longer I think builder and buffer are about equal (builder is slightly faster because it's not synchronized).
here is an example to read and concatenate 2 string without using 3rd variable:
public class Demo {
public static void main(String args[]) throws Exception {
InputStreamReader r=new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(r);
System.out.println("enter your first string");
String str1 = br.readLine();
System.out.println("enter your second string");
String str2 = br.readLine();
System.out.println("concatenated string is:" + str1 + str2);
}
}
There are multiple ways to do so, but Oracle and IBM say that using +, is a bad practice, because essentially every time you concatenate String, you end up creating additional objects in memory. It will utilize extra space in JVM, and your program may be out of space, or slow down.
Using StringBuilder or StringBuffer is best way to go with it. Please look at Nicolas Fillato's comment above for example related to StringBuffer.
String first = "I eat"; String second = "all the rats.";
System.out.println(first+second);
Using "+" symbol u can concatenate strings.
String a="I";
String b="Love.";
String c="Java.";
System.out.println(a+b+c);
So I'm still shaky on how basic java works, and here is a method I wrote but don't fully understand how it works anyone care to explain?
It's supposed to take a value of s in and return it in its reverse order.
Edit: Mainly the for loop is what is confusing me.
So say I input "12345" I would want my output to be "54321"
Public string reverse(String s){
String r = "";
for(int i=0; i<s.length(); i++){
r = s.charAt(i) + r;
}
return r;
}
We do a for loop to the last index of String a , add tha carater of index i to the String s , add here is a concatenation :
Example
String z="hello";
String x="world";
==> x+z="world hello" #different to z+x ="hello world"
for your case :
String s="";
String a="1234";
s=a.charAt(0)+s ==> s= "1" + "" = "1" ( + : concatenation )
s=a.charAt(1)+s ==> s='2'+"1" = "21" ( + : concatenation )
s=a.charAt(2)+s ==> s='3'+"21" = "321" ( + : concatenation )
s=a.charAt(3)+s ==> s='3'+"321" = "4321" ( + : concatenation )
etc..
public String reverse(String s){
String r = ""; //this is the ouput , initialized to " "
for(int i=0; i<s.length(); i++){
r = s.charAt(i) + r; //add to String r , the caracter of index i
}
return r;
}
What this code does is the following
Create a new variable r="";
then looping for the string in input lenght it adds at the beginning of r the current character of the loop.
i=0) r="1"
i=1) r="21"
i=2) r="321"
i=3) r="4321"
i=4) r="54321"
When you enter the loop you are having empty string in r.
Now r=""
In 1st iteration, you are taking first character (i=0) and appending r to it.
r = "1" + "";
Now r=1
In 2nd iteration, you are taking second character (i=1) and appending r to it
r = "2" + "1";
Now r=21
You can trace execution on a paper like this, then you will easily understand what is happening.
What the method is doing is taking the each character from the string s and putting it at the front of the new string r. Renaming the variables may help illustrate this.
public String reverse(String s){
String alreadyReversed = "";
for(int i=0; i<s.length(); i++){
//perform the following until count i is as long as string s
char thisCharacterInTheString = s.charAt(i); // for i==0 returns first
// character in passed String
alreadyReversed = thisCharacterInTheString + alreadyReversed;
}
return alreadyReversed;
}
So in the first iteration of the for loop alreadyReversed equals 1 + itself (an empty string).
In the second iteration alreadyReversed equals 2 + itself (1).
Then 3 + itself (21).
Then 4 + 321.
Then 5 + 4321.
GO back to your problem statement (take an input string and produce an output string in reverse order). Then consider how you would do this (not how to write Java code to do this).
You would probably come up with two alternatives:
Starting at the back of the input string, get one character at a time and form a new string (thus reversing its order).
Starting at the front of the string, get a character. Then for each next character, put it in front of all the characters you have created so far.
Your pseudo code results might be like the following
Option 1
let l = the length of the input string
set the output string to ""
while l > 0
add the "lth" character of the input string to the output string
subtract 1 from l
Option 2 left as an exercise for the questioner.
Then you would consider how to write Java to handle your algorithm. You will find that there are several ways to get the "lth" character of a string. First, in Java a string of length l has characters in position 0 through l-1. You can use string.charAt(loc) or string.substring(loc,loc+1) to get the character at position loc
I have two strings plainText and key. Now, if the plainText.length > key.length then i have to repeat the key until its the same length as that of plainText. here's an example:
plainText = "helloworld"
key="foobar"
hence the key should be increased to "foobarfoob".
One solution is to repeat the entire word and then remove the last characters until it reaches the same length as of plainText like "foobarfoobar" and then remove the characters "ar" .
Is there any better (or rather and Elegant) way to do this in java?
Your solution seems reasonable, other than the way you remove the last characters - don't do it one at a time, just use substring or StringBuilder.setLength():
// Make sure we never have to expand...
StringBuilder builder = new StringBuilder(plainText.length() + key.length() - 1);
while (builder.length() < plainText.length()) {
builder.append(key);
}
builder.setLength(plainText.length());
String result = builder.toString();
Or just change the append call to only get to the right size:
StringBuilder builder = new StringBuilder(plainText.length());
while (builder.length() < plainText.length()) {
builder.append(key.substring(0, Math.min(key.length(),
builder.length() - plainText.length()));
}
String result = builder.toString();
Personally I prefer the first - it's simpler.
My proposal (admittedly not very self-explanatory, but compact and efficient) - it repeats key as many times as necessary + 1 and uses substring to remove the extra characters:
public static void main(String[] args) throws Exception {
String plainText = "helloworld";
String key = "foobar";
int repeat = plainText.length() / key.length();
int remainder = plainText.length() % key.length();
String result = new String(new char[repeat + 1]).replaceAll(".", key).substring(0, key.length() * repeat + remainder);
System.out.println(result);
}
you can loop over key and in every step count the steps(which should be some time equal to plaintext => stop) and add those chars of every step to key. this is done in one loop
String a="(Yeahhhh) I have finally made it to the (top)";
Given above String, there are 4 of '(' and ')' altogether.
My idea of counting that is by utilizing String.charAt method. However, this method is rather slow as I have to perform this counting for each string for at least 10000 times due to the nature of my project.
Anyone has any better idea or suggestion than using .chartAt method?????
Sorry for not explaining clearly earlier on, what I meant for the 10000 times is for the 10000 sentences to be analyzed which is the above String a as only one sentence.
StringUtils.countMatches(wholeString, searchedString) (from commons-lang)
searchedString may be one-char - "("
It (as noted in the comments) is calling charAt(..) multiple times. However, what is the complexity? Well, its O(n) - charAt(..) has complexity O(1), so I don't understand why do you find it slow.
Sounds like homework, so I'll try to keep it at the "nudge in the right direction".
What if you removed all characters NOT the character you are looking for, and look at the length of that string?
There is a String method that will help you with this.
You can use toCharArray() once and iterate over that. It might be faster.
Why do you need to do this 10000 times per String? Why don't you simply remember the result of the first time? This would save a lot more than speeding up a single counting.
You can achieve this by following method.
This method would return a map with key as the character and value as its occurence in input string.
Map countMap = new HashMap();
public void updateCountMap(String inStr, Map<Character, Integer> countMap)
{
char[] chars = inStr.toCharArray();
for(int i=0;i<chars.length;i++)
{
if(!countMap.containsKey(chars[i]))
{
countMap.put(chars[i], 1);
}
countMap.put(chars[i] ,countMap.get(chars[i])+1);
}
return countMap;
}
What we can do is read the file line by line and calling the above method for every line. Each time the map would keep adding the values(number of occurences) for characters. Thus, the Character array size would never be too long and we achieve what we need.
Advantage:
Single iteration over the input string's characters.
Character array size never grows to high limits.
Result map contains occurences for each character.
Cheers
You could do that with Regular Expressions:
Pattern pattern = Pattern.compile("[\\(\\)]"); //Pattern says either '(' or ')'
Matcher matcher = pattern.matcher("(Yeahhhh) I have finally made it to the (top)");
int count = 0;
while (matcher.find()) { //call find until nothing is found anymore
count++;
}
System.out.println("count "+count);
The Pro is, that the Patterns are very flexible. You could also search for embraced words: "\\(\\w+\\)" (A '(' followed by one or more word characters, followed by ')')
The Con is, that it may be like breaking a fly on the wheel for very simple cases
See the Javadoc of Pattern for more details on Regular Expressions
I tested the following methods for 10M strings to count "," symbol.
// split a string by ","
public static int nof1(String s)
{
int n = 0;
if (s.indexOf(',') > -1)
n = s.split(",").length - 1;
return n;
} // end method nof1
// count "," using char[]
public static int nof2(String s)
{
char[] C = s.toCharArray();
int n = 0;
for (char c : C)
{
if (c == ',')
n++;
} // end for c
return n;
} // end method nof2
// replace "," and calculate difference in length
public static int nof3(String s)
{
String s2 = s.replaceAll(",", "");
return s.length() - s2.length();
} // end method nof3
// count "," using charAt
public static int nof4(String s)
{
int n = 0;
for(int i = 0; i < s.length(); i++)
{
if (',' == s.charAt(i) )
n++;
} // end for i
return n;
} // end method nof4
// count "," using Pattern
public static int nof5(String s)
{
// Pattern pattern = Pattern.compile(","); // compiled outside the method
Matcher matcher = pattern.matcher(s);
int n = 0;
while (matcher.find() )
{
n++;
}
return n;
} // end method nof5
The results:
nof1: 4538 ms
nof2: 474 ms
nof3: 4357 ms
nof4: 357 ms
nof5: 1780 ms
So, charAt is the fastest one. BTW, grep -o ',' | wc -l took 7402 ms.