String - Yash-777/LearnJava GitHub Wiki
The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.
public String intern()
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
String ReverseObject, memory address, {equals (==)}
public class ReverseObject {
public static void main(String[] args) {
// String is immutable Object, once created we cannot change the object
//The SCP is an area inside the heap memory. It contains the unique strings.
//In order to put the strings in the string pool, one needs to call the intern().
String s1_scp = "Yash";
System.out.println("SCP intern():"+s1_scp.intern());
String s2_scp = "Yash";
System.out.println("SCP intern():"+s2_scp.intern());
String s3_h = new String("Yash");
String s4_h = new String("Yash");
System.out.println("Memory Address & Content :"+ (s1_scp == s2_scp));
System.out.println("Memory Address & Content :"+ (s3_h == s4_h));
System.out.println("Content :"+ s1_scp.equals(s2_scp) );
System.out.println("Content :"+ s3_h.equals(s4_h));
String str = "Yashwanth";
stringReverse(str, false);
stringReverse(str, true);
int num = 1234;
reverseNumberString(num);
reverseNumber(num);
StringBuffer buff = new StringBuffer(str);
System.out.println("String Buffer : "+ buff.reverse());
// Use List interface to reverse string.
char[] ch = str.toCharArray();
List<Character> reverse = new LinkedList<>();
for (int i = ch.length - 1; i >= 0; i--) {
reverse.add(ch[i]);
}
System.out.println("Reverse of a String with LIST : "+ reverse);
}
public static String stringReverse(String str, boolean isDistinct) {
char[] ch = str.toCharArray();
String reverse = "";
for (int i = ch.length - 1; i >= 0; i--) {
if ( isDistinct && !(reverse.indexOf(ch[i]) > -1) ) // Remove duplicates
reverse += ch[i];
if (!isDistinct) reverse += ch[i];
}
System.out.println("Reverse of a String: "+ reverse +", DISTINCT:"+isDistinct);
return reverse;
}
public static int reverseNumberString(int num) {
String str = new Integer(num).toString();
char[] ch = str.toCharArray();
String reverse = "";
for (int i = ch.length - 1; i >= 0; i--) {
reverse += ch[i];
}
System.out.println("Reverse of a String Number : "+ reverse);
return Integer.parseInt(reverse);
}
public static int reverseNumber(int num) {
int temp = num;
int rev = 0;
int sum = 0; // sumOfDigits
while (temp > 0 ) {
rev = (rev * 10) + temp % 10;
sum += temp % 10;
temp = temp / 10;
}
System.out.println("Reverse of a Number : "+ rev);
System.out.println("Sum of Digits of a Number : "+ sum);
if(rev == num) {
System.out.println("Polyndrome Number : [121 = 121]");
}
return rev;
}
}
Hash Code Collision in Java Strings - The behavior of String's hashCode(), equals(), and == operator — specifically using a known hash code collision.
String[Aa], Hash[2112], System Hash[366712642]
String[BB], Hash[2112], System Hash[1829164700] 📄 Java Class: **`StringHashCollisionExample.java`** This example illustrates how Java's String class behaves when comparing strings using:
/**
* Demonstrates the difference between ==, equals(), and hashCode() using Strings in Java.
* Also shows an example of a hash code collision between two distinct strings: "Aa" and "BB".
*
* Key Concepts:
* - `==` checks reference equality (same object in memory)
* - `equals()` checks logical/content equality
* - `hashCode()` provides a numeric representation used in hash-based collections like HashMap
*
* ⚠️ Even if two strings have the same hash code, they may not be equal.
*
* Usage:
* - Run this class as a Java application to see the behavior printed in the console.
*
* @author 🔐 Yash
*/
public class StringHashCollisionExample {
public static void main(String[] args) {
String s1 = "Aa";
String s2 = "BB";
System.out.println("String s1 = \"Aa\";");
System.out.println("String s2 = \"BB\";\n");
System.out.println("s1 == s2: " + (s1 == s2));
System.out.println("s1.equals(s2): " + s1.equals(s2));
System.out.println("s1.hashCode(): " + s1.hashCode());
System.out.println("s2.hashCode(): " + s2.hashCode());
System.out.println("\nSummary:");
if (s1.hashCode() == s2.hashCode()) {
System.out.println("- Hash codes are equal (collision): " + s1.hashCode());
}
if (!s1.equals(s2)) {
System.out.println("- But strings are not equal: \"" + s1 + "\" != \"" + s2 + "\"");
}
}
}
Java computes the hash code for a string like this: // s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
public int hashCode() {
int h = 0;
for (int i = 0; i < value.length; i++) {
h = 31 * h + value[i];
}
return h;
} Using this logic:
ASCII Codes Table
❗ Important Note: Even if two objects have the same hash code, they are not guaranteed to be equal, and == doesn’t care about hash codes at all. It’s only about whether they’re the exact same object. |
String Trim special chars Unicode's 1.1, general_punctuation, invisible-characters-unwanted
- String equals Unicodes chars "My Sample Space Data"
String s1 = "My Sample Space Data", s2 = "My Sample Space Data";
System.out.format("S1: %s\n", java.util.Arrays.toString(s1.getBytes()));
System.out.format("S2: %s\n", java.util.Arrays.toString(s2.getBytes()));
-
View non-printable unicode characters -
All codes: ␈␠ 〿
Trim example with Unicodes chars
public class StringUtil {
public static void main(String[] args) {
//String text = " Hello World! \uFEFF\u200B\u00A0 "; // Example string with various spaces
String text = " Hello World! - "+getUnicodeSpaces(); // \u2060-\u237D-\uFEFF
// Print the original and trimmed text
System.out.println("Original text: \"" + text + "\"");
System.out.println("Original text: \"" + text.trim() + "\""); // Space, TabSpace
System.out.println("Trimmed text: \"" + trimSpaces(text) + "\"");
System.out.println("Trimmed text: \"" + trimAdvanced(text, getUnicodeSpaces()) + "\"");
}
//@Data - Only supported on the class, @Setter - On Class/Fields
@AllArgsConstructor @NoArgsConstructor @Getter
enum Unicodes {
WHITESPACE("\u0020", ".", "SP - WhiteSpace"),
// # FORMAT chars
ENSP ("\u2002", "ENSP", "EN SPACE"),
EMSP ("\u2003", "EMSP", "EM SPACE"),
EMSP3("\u2004", "3/EMSP", "THREE-PER-EM SPACE"),
EMSP4("\u2005", "4/EMSP", "FOUR-PER-EM SPACE"),
EMSP6("\u2006", "6/EMSP", "SIX-PER-EM SPACE"),
FSP ("\u2007", "FSP", "FIGURE SPACE"),
PSP ("\u2008", "PSP", "PUNCTUATION SPACE"),
THSP ("\u2009", "THSP", "THIN SPACE"),
HSP ("\u200A", "HSP", "HAIR SPACE"),
ZWSP ("\u200B", "ZWSP", "ZERO WIDTH SPACE"),
ZWNJ ("\u200C", "ZWNJ", "ZERO WIDTH NON-JOINER"),
ZWJ ("\u200D", "ZWJ", "ZERO WIDTH JOINER"),
LRM ("\u200E", "LRM", "LEFT-TO-RIGHT MARK"),
RLM ("\u200F", "RLM", "RIGHT-TO-LEFT MARK"),
LS ("\u2028", "LS", "LINE SEPARATOR"),
PS ("\u2029", "PS", "PARAGRAPH SEPARATOR"),
LRE ("\u202A", "LRE", "LEFT-TO-RIGHT EMBEDDING"),
RLE ("\u202B", "RLE", "RIGHT-TO-LEFT EMBEDDING"),
PDF ("\u202C", "PDF", "POP DIRECTIONAL FORMATTING"),
LRO ("\u202D", "LRO", "LEFT-TO-RIGHT OVERRIDE"),
RLO ("\u202E", "RLO", "RIGHT-TO-LEFT EMBEDDING"),
NNBSP("\u202F", "NNBSP", "ZERO WIDTH SPACE"),
MMSP("\u205F", "MMSP", "MEDIUM MATHEMATICAL SPACE"),
WJ ("\u2060", "WJ", "WORD JOINER"),
ZWNBSP("\uFEFF", "ZWNBSP", "ZERO WIDTH NO-BREAK SPACE"),
// # INVISIBLE chars
FA ("\u2061", "(FA)", "Function application"),
IT ("\u2062", "(IT)", "invisible times"),
IS ("\u2063", "(IS)", "invisible separator"),
IP ("\u2064", "(IP)", "invisible plus"),
// # DEPRECATED chars
ISS ("\u206A", "ISS", "INHIBIT SYMMETRIC SWAPPING"),
ASS ("\u206B", "ASS", "ACTIVATE SYMMETRIC SWAPPING"),
IAFS ("\u206C", "IAFS", "INHIBIT ARABIC FORM SHAPING"),
AAFS ("\u206D", "AAFS", "ACTIVATE ARABIC FORM SHAPING"),
NADS ("\u206E", "NADS", "NATIONAL DIGIT SHAPES"),
NODS ("\u206F", "NODS", "NOMINAL DIGIT SHAPES"),
NBSP ("\u00A0", "NBSP", "NO-BREAK SPACE ( )"),
BACKSPACE1("\u0008", "BKSP", "BACKSPACE"),
BACKSPACE("\u2408", "BS", "SYMBOL FOR BACKSPACE (␈)"),
SPACE("\u2420", "SP", "SYMBOL FOR SPACE (␠)"),
IDSP("\u3000", "IDSP", "IDEOGRAPHIC SPACE"),
IHSPACE("\u303F", "ZWSP", "IDEOGRAPHIC HALF FILL SPACE"),
TAB(" ", "TAB", "TAB SPACE"),
;
private String CODE, NAME, DESCRIPTION;
}
public static String getUnicodeSpaces() {
// Get the size of the enum
//System.out.println("Size of enum: " + Unicodes.values().length);
// Append all CODE values to a string
StringBuilder codesStringBuilder = new StringBuilder();
for (Unicodes unicode : Unicodes.values()) {
codesStringBuilder.append(unicode.getCODE());
}
String allCodes = codesStringBuilder.toString();
//System.out.println("All codes: " + allCodes);
return allCodes;
}
// Define a regular expression to match all kinds of spaces
public static String trimSpaces(String text) {
//String spaceTrimRegexLeading = "^["+ Pattern.quote(getUnicodeSpaces()) +"]+"; //
// Match leading and trailing spaces
String spaceTrimRegex = "^[" + Pattern.quote(getUnicodeSpaces()) + "]+|[" + Pattern.quote(getUnicodeSpaces()) + "]+$";
return text.replaceAll(spaceTrimRegex, "");
}
public static String trimAdvanced(String value, String skipString) {
Objects.requireNonNull(value);
int strLength = value.length();
if (strLength == 0) return value;
int len = value.length();
int st = 0;
char[] val = value.toCharArray();
// Trim leading characters specified in skipString
while ((st < len) && (skipString.indexOf(val[st]) >= 0)) {
st++;
}
// Trim trailing characters specified in skipString
while ((st < len) && (skipString.indexOf(val[len - 1]) >= 0)) {
len--;
}
// Return trimmed substring
return (st > len) ? "" : ((st > 0) || (len < strLength)) ? value.substring(st, len) : value;
}
}
String PayLoad Validation
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
PayLoad
{
"employees": {
"employee": {
"id": "1",
"firstName": "Tom",
"postalCode": [
10
],
"address": {
"pin": "123"
},
"lastName": "Cruise"
}
}
}
import org.apache.commons.lang3.StringUtils;
public class StringPayload {
public static String payLoadInSingleLine(String payload) {
// Convert payLoad string to byte array
byte[] bytes = payload.getBytes(StandardCharsets.UTF_8);
// Create ByteArrayInputStream from byte array
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
// Create InputStreamReader from ByteArrayInputStream
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
// Now you can use the reader for further processing
String requestBody = new BufferedReader(reader).lines().reduce(String::concat).get();
return requestBody;
}
public static void main(String[] args) {
String payload = "";
String requestBody = payLoadInSingleLine(payload);
System.out.println(requestBody.length() +" - requestBody :"+requestBody);
// Replace multiple spaces with a single space using regular expression
String result = requestBody.replaceAll("\\s+", " ");
System.out.println(result.length() +" - Replace multiple spaces :"+result);
System.out.println("isValidJson(jsonStr): " + isValidPayload(result));
System.out.println("getJsonString(jsonStr): " + getJsonString(result));
System.out.println("validateAndConvertJsonToMap(jsonStr): " + validateAndConvertJsonToMap(result));
}
public static Map<String, Object> validateAndConvertJsonToMap(String json) { // readValue
try {
if(json != null)
return new com.fasterxml.jackson.databind.ObjectMapper()
.readValue(json,
new com.fasterxml.jackson.core.type.TypeReference<java.util.HashMap<String, Object>>() {});
} catch (Exception e) {
System.err.println("Invalid JSON: " + e.getMessage());
}
return null; // Return null if the JSON is invalid
}
public static boolean isValidPayload(String payload) { // readTree
ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
objectMapper.configure(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
objectMapper.readTree(payload);
return true; // Valid JSON
} catch (com.fasterxml.jackson.core.JsonProcessingException e) {
System.out.println("--- JsonProcessingException:"+ e.getLocalizedMessage());
return Boolean.FALSE; // Invalid JSON
}
}
private static String getJsonString(String payload) {
System.out.println("Parse the JSON string to either JSONObject or JSONArray");
Object json;
try {
json = new org.json.JSONObject( payload );
} catch (org.json.JSONException e) {
try {
System.out.println("===== JSON-Object::"+ e.getLocalizedMessage());
json = new org.json.JSONArray( payload );
} catch (org.json.JSONException ex) {
System.out.println("===== JSON-Array::"+ ex.getLocalizedMessage());
//throw new IllegalArgumentException("Invalid JSON format");
System.err.println("=== Invalid JSON Ex:"+ payload);
return payload;
}
}
return json.toString();
}
}
function isValidJson(jsonString) {
try {
JSON.parse(jsonString);
return { isValid: true, errorMessage: null }; // JSON is valid
} catch (error) {
return { isValid: false, errorMessage: error.message }; // JSON is invalid
}
}
const payload = ``;
const validationResult = isValidJson(payload);
console.log("Is valid JSON:", validationResult.isValid);
if (!validationResult.isValid) {
console.log("Error message:", validationResult.errorMessage);
}
intern() « Before saving in String Constant Pool(SCP) it invokes intern() method to check object availability with same content in pool using equals method. If String-copy is available in the Pool then returns the reference. Otherwise, String object is added to the pool and returns the reference.
hash() « String @override hash() of Object class to generate same hash code for sequence of characters.
equals and ==
« ==
operator is to check the hash code where as equals()
method is to check the content of a String.
immutable «
What's the difference between length and length()
int[] myArray = new int[10];
String myString = "hello world!";
List<int> myList = new ArrayList<int>();
myArray.length //gives the length of the array
myString.length() //gives the length of the string
myList.size() //gives the length of the list
String reverse program.
public static String reverseStr(String str) {
//String str = "Yashwanth"; //https://stackoverflow.com/a/59166517/5081877
String collect = IntStream.range(0, str.length())
.boxed().sorted(Collections.reverseOrder())
.map(i -> {
System.out.println(i);
return String.valueOf(str.charAt(i));
})
.distinct().collect(Collectors.joining("")); //htnawsY
//.collect(Collectors.joining("")); //htnawhsaY
//.collect(Collectors.joining(".")); //h.t.n.a.w.h.s.a.Y
System.out.println("Reverse Str:"+collect);
return collect;
}