Java String pool Storage doubts [duplicate] - java

This question already has answers here:
Testing string equality using hashCode()
(10 answers)
Closed 9 years ago.
why hashcode are same of string object ???
I'm trying to understand how string pool works.I have gone through many sites and finally i'm more confused now. Let me put down my doubts here. Someone help me in understanding them.
class cov {
public static void main(String[] args) {
String s = "abc"; //Object on string pool
System.out.println(s.hashCode());
String str = new String("abc"); //This statement does two things
System.out.println(str.hashCode());
}
}

A String's hashCode() method is calculated based on the chars it contains. If two String objects contain the same chars with the same case and in the same order, then they will have the same hashCode().

The String class has a hashCode method that calculates the hash code from its content, not from its memory location. So if two strings are identical (but not necessarily equal), they will have the same hash code.
If this were not the case, a structure such as HashSet<String> would be unusable - every new String would turn out not to be in the set, even when a String with the same characters had already been added.

Below is the source code which is used for generating hashCode
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
And as described in other answers hashCode is generated from the contents of the String not the place where it is residing. e.g heap stack or constant pool

Related

difference between creating java string with and without new operator [duplicate]

This question already has answers here:
What is the difference between strings allocated using new operator & without new operator in java J2ME?
(5 answers)
Closed 8 years ago.
With new operator String create the string in heap and put a copy in string const pool so the result of hashcode is same in below case;
String s1 = new String("Test");
String s2 = new String("Test");
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
But without using new operator its still giving the same hashcode
String s1 = new String("Test");
String s2 = "Test";
System.out.println(s1.hashCode() + " "+ s2.hashCode() + " " + s1.equals(s2));
Then what is the differnce between above two notation of string creation although they are referening to same string in string const. pool
Based on Effective java.
It is often appropriate to reuse a single object instead of creating a
new function- ally equivalent object each time it is needed. Reuse can
be both faster and more stylish. An object can always be reused if it
is immutable. As an extreme example of what not to do,
consider this statement:
String s = new String("stringette"); // DON'T
DO THIS!
The statement creates a new String instance each time it is
executed, and none of those object creations is necessary. The
argument to the String construc- tor ( "stringette" ) is itself a
String instance, functionally identical to all of the objects created
by the constructor. If this usage occurs in a loop or in a frequently
invoked method, millions of String instances can be created
needlessly.
The improved version is simply the following:
String s = "stringette";
This version uses a single String instance, rather than creating a new
one each time it is executed. Furthermore, it is guaranteed that the
object will be reused by any other code running in the same virtual
machine that happens to con- tain the same string literal
therefore creating unnecessary new Object of String or any other Objects are expensive.
From docs and Java.lang.String class, Internal Implementation of hashCode()
/**
* Returns a hash code for this string. The hash code for a
* String object is computed as
*
* s[0]*31^(n-1) + s1*31^(n-2) + ... + s[n-1]
*
* using int arithmetic, where s[i] is the
* ith character of the string, n is the length of
* the string, and ^ indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* #return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
More about String hashcode here
Both expression gives you String object, but there is difference between them. When you create String object using new() operator, it always create a new object in heap memory. On the other hand, if you create object using String literal syntax e.g. String s2 = "Test"; it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists. Otherwise it will create a new string object and put in string pool for future re-use.
for further reading see:here
String str = new String("String");
always create a new object on the heap.
Here creates a new String having for value the value of the constant "String" and assignates its reference to the variable str.
String str = "String";
uses the String pool
Here assignates the reference associated to the constant "String" to the variable str

Why will this java string routine not print the answer?

I have been working on the Project Euler problem 4. I am new to java, and believe I have found the answer (906609 = 993 * 913, by using Excel!).
When I print the line commented out, I can that my string manipulations have worked. I've researched a few ways to compare strings in case I had not understoof something, but this routine doesn't give me a result.
Please help me identify why it is not printing the answer?
James
public class pall{
public static void main(String[] args){
int i;
int j;
long k;
String stringProd;
for(i=994;i>992; i--){
for (j=914;j>912; j--){
k=(i*j);
stringProd=String.valueOf(k);
int len=stringProd.length();
char[] forwards=new char[len];
char[] back = new char[len];
for(int l=0; l<len; l++){
forwards[l]=stringProd.charAt(l);
}
for(int m=0; m<len;m++){
back[m]=forwards[len-1-m];
}
//System.out.println(forwards);
//System.out.println(back);
if(forwards.toString().equals(back.toString())){
System.out.println(k);}
}
}
}
}
You are comparing the string representation of your array. toString() doesn't give you what you think. For example, the below code makes it clear:
char[] arr1 = {'a', 'b'};
char[] arr2 = {'a', 'b'};
System.out.println(arr1.toString() + " : " + arr2.toString());
this code prints:
[C#16f0472 : [C#18d107f
So, the string representation of both the arrays are different, even though the contents are equal. This is because arrays don't override toString() method. It inherits the Object#toString() method.
The toString method for class Object returns a string consisting of
the name of the class of which the object is an instance, the at-sign
character #, and the unsigned hexadecimal representation of the hash
code of the object. In other words, this method returns a string equal
to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
So, in the above output, [C is the output of char[].class.getName(), and 18d107f is the hashcode.
You can't also compare the arrays using forward.equals(back), as arrays in Java don't override equals() or hashCode() either. Any options? Yes, for comparing arrays you can use Arrays#equals(char[], char[]) method:
if (Arrays.equals(forward, back)) {
System.out.println(k);
}
Also, to get your char arrays, you don't need those loops. You can use String#toCharArray() method. And also to get the reverse of the String, you can wrap the string in a StringBuilder instance, and use it's reverse() method:
char[] forwards = stringProd.toCharArray();
char[] back = new StringBuilder(stringPod).reverse().toString().toCharArray();
And now that you have found out an easy way to reverse a string, then how about using String#equals() method directly, and resist creating those character arrays?
String stringPod = String.valueOf(k);
String reverseStringPod = new StringBuilder(stringPod).reverse().toString()
if (stringPod.equals(reverseStringPod)) {
System.out.println(k);
}
Finally, since it is about project euler, which is about speed and mostly mathematics. You should consider avoiding String utilities, and do it with general division and modulus arithmetic, to get each individual digits, from beginning and end, and compare them.
To convert a string to char[] use
char[] forward = stringProd.toCharArray();
To convert a char[] to String, use String(char[]) constructor:
String backStr = new String(back); // Not the same as back.toString()
However, this is not the most performant solution, for several reasons:
You do not need to construct a back array to check if a string is a palindrome - you can walk the string from both ends, comparing the characters as you go, until you either find a difference or your indexes meet in the middle.
Rather than constructing a new array in a loop, you could reuse the same array - in case you do want to continue with an array, you could allocate it once for the maximum length of the product k, and use it in all iterations of your loop.
You do not need to convert a number to string in order to check if it is a palindrome - you can get its digits by repeatedly taking the remainder of division by ten, and then dividing by ten to go to the next digit.
Here is an illustration of the last point:
boolean isPalindrome(int n) {
int[] digits = new int[10];
if (n < 0) n = -n;
int len = 0;
while (n != 0) {
digits[len++] = n % 10;
n /= 10;
}
// Start two indexes from the opposite sides
int left = 0, right = len-1;
// Loop until they meet in the middle
while (left < right) {
if (digits[left++] != digits[right--]) {
return false;
}
}
return true;
}

Hashcode value is same

why hashcode value is same?
public static void main(String args[])
{
String s1="abc";
String s2=new String("abc");
System.out.println("Hashcode s1-:"+ s1.hashCode());
System.out.println("Hashcode s2-:"+ s2.hashCode());
if(s1==s2){
System.out.println("==true:");
}
}
output
Hashcode s1-:96354
Hashcode s2-:96354
The hash code for two equal objects should be equal.
In this case, the objects are strings and they are considered equal because they hold the same sequence of characters, "abc".
If you want a hash code that is based on object identity rather than equality use System.identityHashCode().
Why wouldn't they be the same? The hashcode is computed on the contents of the string, hence they are the same for both.
== compares object references, and because you used new String for s2 the references are not the same.
You should be using the equals method to test equality of strings based on their value.
Because the hashcode is computed using the formula which takes in only the characters present in the string. Same characters in a String will yield the same hashcode.
Javadoc for the computation formula.
This is because of how the hashcode of String are computed in java.
Check the javadoc : http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
And more over, your two strings are equals, therefore their hashcode must be the same.
This is the code...therefore the result is the same for two equals objects:
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
as per the rules, objects for those equals method return true, should have the same hashcode.
Hashcode for a string is computed based on its characters and so is equals()
It is calculated as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
where s[i] is each character for 0<=i<n and n is its length.
Both your strings have the same content and thus hashcode is the same.
String class has its own hashcode method implemeted in it. Its method will compute the hashcode as: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
So for the same character sequence hashcode will be same.
The JVM doesn't create a new String if this already exist, it just returns the reference. A new String will be created when you try to change the actual String in one of the vars.
You can check it debugging the application, the String objects will have different memory addresses but the value inside will have exactly the same memory address.

A particular type of hash on a String concatenation

I need a specialised hash function h(X,Y) in Java with the following properties.
X and Y are strings.
h(X,Y) = h(Y,X).
X and Y are arbitrary length strings and there is no length limit on the result of h(X,Y) either.
h(X,Y) and h(Y,X) should not collide with h(A,B) = h(B,A) if X is not equal to A and Y is not equal to B.
h() does not need to be a secure hash function unless it is necessary to meet the aforementioned requirements.
Fairly high-performant but this is an open-ended criterion.
In my mind, I see requirements 2 and 4 slightly contradictory but perhaps I am worrying too much.
At the moment, what I am doing in Java is the following:
public static BigInteger hashStringConcatenation(String str1, String str2) {
BigInteger bA = BigInteger.ZERO;
BigInteger bB = BigInteger.ZERO;
for(int i=0; i<str1.length(); i++) {
bA = bA.add(BigInteger.valueOf(127L).pow(i+1).multiply(BigInteger.valueOf(str1.codePointAt(i))));
}
for(int i=0; i<str2.length(); i++) {
bB = bB.add(BigInteger.valueOf(127L).pow(i+1).multiply(BigInteger.valueOf(str2.codePointAt(i))));
}
return bA.multiply(bB);
}
I think this is hideous but that's why I am looking for nicer solutions. Thanks.
Forgot to mention that on a 2.53GHz dual core Macbook Pro with 8GB RAM and Java 1.6 on OS X 10.7, the hash function takes about 270 micro-seconds for two 8 (ASCII) character Strings. I suspect this would be higher with the increase in the String size, or if Unicode characters are used.
why not just add their hashCode's together?
Today I've decided to add my solution for this hash function problem. It was not tested very good and I did not measure its performance, so you can feed me back with your comments. My solution is situated below:
public abstract class HashUtil {
//determines that we want hash, that has size of 32 integers ( or 32*32 bits )
private static final int hash_size = 32;
//some constants that can be changed in sake of avoiding collisions
private static final BigInteger INITIAL_HASH = BigInteger.valueOf(7);
private static final BigInteger HASH_MULTIPLIER = BigInteger.valueOf(31);
private static final BigInteger HASH_DIVIDER = BigInteger.valueOf(2).pow(32*hash_size);
public static BigInteger computeHash(String arg){
BigInteger hash = new BigInteger(INITIAL_HASH.toByteArray());
for (int i=0;i<arg.length()/hash_size+1;i++){
int[] tmp = new int[hash_size];
for(int j=0;j<Math.min(arg.length()-32*i,32);j++){
tmp[i]=arg.codePointAt(i*hash_size+j);
}
hash = hash.multiply(HASH_MULTIPLIER).add(new BigInteger(convert(tmp)).abs()).mod(HASH_DIVIDER);
}
//to reduce result space to something meaningful
return hash;
}
public static BigInteger computeHash(String arg1,String arg2){
//here I don't forgot about reducing of result space
return computeHash(arg1).add(computeHash(arg2)).mod(HASH_DIVIDER);
}
private static byte[] convert(int[] arg){
ByteBuffer byteBuffer = ByteBuffer.allocate(arg.length*4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(arg);
return byteBuffer.array();
}
public static void main(String[] args){
String firstString="dslkjfaklsjdkfajsldfjaldsjflaksjdfklajsdlfjaslfj",secondString="unejrng43hti9uhg9rhe3gh9rugh3u94htfeiuwho894rhgfu";
System.out.println(computeHash(firstString,secondString).equals(computeHash(secondString,firstString)));
}
}
I suppose that my solution should not produce any collision for single string with length less then 32 (to be more precise, for single string with length less then hash_size variable value). Also it is not very easy to find collisions (as I think). To regulate hash conflicts probability for your particular task you can try another prime numbers instead of 7 and 31 in INITIAL_HASH and HASH_MULTIPLIER variables. What do you think about it? Is it good enought for you?
P.S. I think that it will be much better if you'll try much bigger prime numbers.
3) h(X,Y) and h(Y,X) should not collide with h(A,B) = h(B,A) if X is not equal to A and Y is not equal to B.
I think that this requirement rules any hash function that produces numbers that are smaller (on average) than the original Strings.
Any requirement of no collisions runs into the roadblock of the Pigeonhole Principle.
How strict are you being with requirement 4? If the answer is 'not completely strict' then you could just concatenate the two strings putting the smaller one first (this would result in a collision for h('A', 'B') and h('AB', ''))
If there are any characters which you are sure would never appear in the string values then you could use a single instance as a separator, which would fix the collision above.
From 4-th point we can get that h(x,"") should never collide with h(y,"") until x.equals(y) is true. So, you have no size limits on what produce h(x,y), cause it shoud produce unique result for each unique x. But there are infinite number of unique strings. This is not a correct hash function, I think.
Building on String#hashCode, this is not a perfect hash function, so it does not fulfill condition 4.
public static long hashStringConcatenation(String str1, String str2) {
int h1 = str1.hashCode();
int h2 = str2.hashCode();
if ( h1 < h2 )
{
return ((long)h1)<<32 & h2;
}
else
{
return ((long)h2)<<32 & h1;
}
}
Okay, #gkuzmin's comment made me think why I am doing the powers of 127. So, here's a slightly simpler version of the code. The changes are as follows:
I am no longer doing the powers of 127 but actually concatenating the codePointAt numbers as strings, converting the result into BigInteger for each input string and then adding the two BigIntegers.
To compact the answer, I am doing a mod 2^1024 on the final answer.
Speed is not any better (perhaps a little worse!) but then I think the way I am measuring the speed is not right because it probably also measures the time taken for the function call.
Here's the modified code. Does this fulfill all conditions, albeit 4 for such unfortunate cases where repetitions may occur over the 2^1024 result space?
public static BigInteger hashStringConcatenation(String str1, String str2) {
if(str1==null || str1.isEmpty() || str2 == null || str2.isEmpty()) {
return null;
}
BigInteger bA, bB;
String codeA = "", codeB = "";
for(int i=0; i<str1.length(); i++) {
codeA += str1.codePointAt(i);
}
for(int i=0; i<str2.length(); i++) {
codeB += str2.codePointAt(i);
}
bA = new BigInteger(codeA);
bB = new BigInteger(codeB);
return bA.add(bB).mod(BigInteger.valueOf(2).pow(1024));
}
I've decided to add another answer because #Anirban Basu have proposed another solution. So, I do not know how to provide link to his post and if somebody know how to do it - correct me.
Anirban's solution looks like this:
public static BigInteger hashStringConcatenation(String str1, String str2) {
if(str1==null || str1.isEmpty() || str2 == null || str2.isEmpty()) {
return null;
}
BigInteger bA, bB;
String codeA = "", codeB = "";
for(int i=0; i<str1.length(); i++) {
codeA += str1.codePointAt(i);
}
for(int i=0; i<str2.length(); i++) {
codeB += str2.codePointAt(i);
}
bA = new BigInteger(codeA);
bB = new BigInteger(codeB);
return bA.add(bB).mod(BigInteger.valueOf(2).pow(1024));
}
Your new solution now looks like a hash function, but it still has some problems. I suggest that you should think about this:
Maybe it will be better to throw NullPointerException or IllegalArgumentException when null was used as function argument? Are you sure, that you do not want to compute hash for empty strings?
To concatenate large amount of strings it is better to use StringBuffer instead of + operator. Use of this class will produce huge positive impact on your code performance.
Your hash function is not very secure - it is realy easy to compute strings, which will produce conflict.
You can try this code to check algorithm that can can demonstrate your hash function collision.
public static void main(String[] args){
String firstString=new StringBuffer().append((char)11).append((char)111).toString();
String secondString=new StringBuffer().append((char)111).append((char)11).toString();
BigInteger hash1 = hashStringConcatenation(firstString,"arbitrary_string");
BigInteger hash2 = hashStringConcatenation(secondString,"arbitrary_string");
System.out.println("Is hash equal: "+hash1.equals(hash2));
System.out.println("Conflicted values: {"+firstString+"},{"+secondString+"}");
}
So, It is realy easy to break your hash function. Moreover, it is good that it has 2^1024 result space, but a lot of real life conflicts for your implementation lies in very close and simple strings.
P.S. I think that you should read something about already developed hash algorithms, hash function that failed in a real life (like java String class hash function which computed hash using only 16 first characters in the past) and try to examine your solutions according to your requirements and real life. At least you can try to find hash conflict manually and if you succeed then your solution most likely already has some problems.
Here's my changed code according to #gkuzmin's suggestion:
public static BigInteger hashStringConcatenation(String str1, String str2) {
BigInteger bA = BigInteger.ZERO, bB = BigInteger.ZERO;
StringBuffer codeA = new StringBuffer(), codeB = new StringBuffer();
for(int i=0; i<str1.length(); i++) {
codeA.append(str1.codePointAt(i));
}
for(int i=0; i<str2.length(); i++) {
codeB.append(str2.codePointAt(i));
}
bA = new BigInteger(codeA.toString());
bB = new BigInteger(codeB.toString());
return bA.multiply(bB).mod(BigInteger.valueOf(2).pow(1024));
}
Note that in the result, I now multiply bA with bB instead of adding.
Also, added #gkuzmin's suggested test function:
public static void breakTest2() {
String firstString=new StringBuffer().append((char)11).append((char)111).toString();
String secondString=new StringBuffer().append((char)111).append((char)11).toString();
BigInteger hash1 = hashStringConcatenation(firstString,"arbitrary_string");
BigInteger hash2 = hashStringConcatenation(secondString,"arbitrary_string");
System.out.println("Is hash equal: "+hash1.equals(hash2));
System.out.println("Conflicted values: {"+firstString+"},{"+secondString+"}");
}
and another test with strings having only numeric values:
public static void breakTest1() {
Hashtable<String,String> seenTable = new Hashtable<String,String>();
for (int i=0; i<100; i++) {
for(int j=i+1; j<100; j++) {
String hash = hashStringConcatenation(""+i, ""+j).toString();
if(seenTable.contains(hash)) {
System.out.println("Duplication for " + seenTable.get(hash) + " with " + i + "-" + j);
}
else {
seenTable.put(hash, i+"-"+j);
}
}
}
}
The code runs. Of course, it is not an exhaustive check, but the breakTest1() function does not have any issues. #gkuzmin's function displays the following:
Is hash equal: true
Conflicted values: { o},{o }
Why do the two strings produce the same hash? Because they are effectively working with strings '11111arbitrary_string' in both cases. This is a problem.
How about the slightly modified function now?
public static BigInteger hashStringConcatenation(String str1, String str2) {
BigInteger bA = BigInteger.ZERO, bB = BigInteger.ZERO;
StringBuffer codeA = new StringBuffer(), codeB = new StringBuffer();
for(int i=0; i<str1.length(); i++) {
codeA.append(str1.codePointAt(i)).append("0");
}
for(int i=0; i<str2.length(); i++) {
codeB.append(str2.codePointAt(i)).append("0");
}
bA = new BigInteger(codeA.toString());
bB = new BigInteger(codeB.toString());
return bA.multiply(bB).mod(BigInteger.valueOf(2).pow(1024));
}
Here, we add a separator character "0" between each character codes, so the combination for characters 11 111 and 111 11 will no longer confuse the function because the concatenation will produce 110111 and 111011. However, it still will not break requirement 2 of the original question.
So does this now solve the problem albeit within the limits of the 2^1024 range?

Java - Create a new String instance with specified length and filled with specific character. Best solution? [duplicate]

This question already has answers here:
Simple way to repeat a string
(32 answers)
Closed 4 years ago.
I did check the other questions; this question has its focus on solving this particular question the most efficient way.
Sometimes you want to create a new string with a specified length, and with a default character filling the entire string.
ie, it would be cool if you could do new String(10, '*') and create a new String from there, with a length of 10 characters all having a *.
Because such a constructor does not exist, and you cannot extend from String, you have either to create a wrapper class or a method to do this for you.
At this moment I am using this:
protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
char[] array = new char[length];
int pos = 0;
while (pos < length) {
array[pos] = charToFill;
pos++;
}
return new String(array);
}
It still lacks any checking (ie, when length is 0 it will not work). I am constructing the array first because I believe it is faster than using string concatination or using a StringBuffer to do so.
Anyone else has a better sollution?
Apache Commons Lang (probably useful enough to be on the classpath of any non-trivial project) has StringUtils.repeat():
String filled = StringUtils.repeat("*", 10);
Easy!
Simply use the StringUtils class from apache commons lang project. You have a leftPad method:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
No need to do the loop, and using just standard Java library classes:
protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
if (length > 0) {
char[] array = new char[length];
Arrays.fill(array, charToFill);
return new String(array);
}
return "";
}
As you can see, I also added suitable code for the length == 0 case.
Some possible solutions.
This creates a String with length-times '0' filled and replaces then the '0' with the charToFill (old school).
String s = String.format("%0" + length + "d", 0).replace('0', charToFill);
This creates a List containing length-times Strings with charToFill and then joining the List into a String.
String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));
This creates a unlimited java8 Stream with Strings with charToFill, limits the output to length and collects the results with a String joiner (new school).
String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
In Java 11, you have repeat:
String s = " ";
s = s.repeat(1);
(Although at the time of writing still subject to change)
char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);
To improve performance you could have a single predefined sting if you know the max length like:
String template = "####################################";
And then simply perform a substring once you know the length.
Solution using Google Guava
String filled = Strings.repeat("*", 10);
public static String fillString(int count,char c) {
StringBuilder sb = new StringBuilder( count );
for( int i=0; i<count; i++ ) {
sb.append( c );
}
return sb.toString();
}
What is wrong?
using Dollar is simple:
String filled = $("=").repeat(10).toString(); // produces "=========="
Solution using Google Guava, since I prefer it to Apache Commons-Lang:
/**
* Returns a String with exactly the given length composed entirely of
* the given character.
* #param length the length of the returned string
* #param c the character to fill the String with
*/
public static String stringOfLength(final int length, final char c)
{
return Strings.padEnd("", length, c);
}
The above is fine. Do you mind if I ask you a question - Is this causing you a problem? It seams to me you are optimizing before you know if you need to.
Now for my over engineered solution. In many (thou not all) cases you can use CharSequence instead of a String.
public class OneCharSequence implements CharSequence {
private final char value;
private final int length;
public OneCharSequence(final char value, final int length) {
this.value = value;
this.length = length;
}
public char charAt(int index) {
if(index < length) return value;
throw new IndexOutOfBoundsException();
}
public int length() {
return length;
}
public CharSequence subSequence(int start, int end) {
return new OneCharSequence(value, (end-start));
}
public String toString() {
char[] array = new char[length];
Arrays.fill(array, value);
return new String(array);
}
}
One extra note: it seems that all public ways of creating a new String instance involves necessarily the copy of whatever buffer you are working with, be it a char[], a StringBuffer or a StringBuilder. From the String javadoc (and is repeated in the respective toString methods from the other classes):
The contents of the character array are copied; subsequent modification of
the character array does not affect
the newly created string.
So you'll end up having a possibly big memory copy operation after the "fast filling" of the array. The only solution that may avoid this issue is the one from #mlk, if you can manage working directly with the proposed CharSequence implementation (what may be the case).
PS: I would post this as a comment but I don't have enough reputation to do that yet.
Try this Using the substring(int start, int end); method
String myLongString = "abcdefghij";
if (myLongString .length() >= 10)
String shortStr = myLongString.substring(0, 5)+ "...";
this will return abcde.
Mi solution :
pw = "1321";
if (pw.length() < 16){
for(int x = pw.length() ; x < 16 ; x++){
pw += "*";
}
}
The output :
1321************
Try this jobber
String stringy =null;
byte[] buffer = new byte[100000];
for (int i = 0; i < buffer.length; i++) {
buffer[i] =0;
}
stringy =StringUtils.toAsciiString(buffer);

Categories