IT234 Object Oriented Programming with Java

Object Oriented Programming with JavaUnit 815 min read

Strings, Wrapper Classes & Java Type Conversion

Unit 8 of Object Oriented Programming with Java covers string manipulation (methods, immutability, regex), wrapper classes (autoboxing, unboxing), and type conversion (casting, parsing, and instanceof). Learn how to handle text data, convert primitives to objects, and avoid common pitfalls in Java I/O and data processi

TAKEAWAYS:

  • Strings in Java are immutable, so operations like concatenation create new objects—use StringBuilder for efficiency.
  • Wrapper classes (e.g., Integer, Double) convert primitives to objects and vice versa via autoboxing/unboxing.
  • Type conversion requires explicit casting for widening (e.g., int→double) and narrowing (e.g., double→int), with potential data loss.
  • Regular expressions (Pattern, Matcher) enable powerful text validation (e.g., email, phone numbers).
  • Parsing (e.g., Integer.parseInt()) converts strings to primitives, while valueOf() converts to wrapper objects.
  • Common pitfalls: NullPointerException (uninitialized strings), incorrect casting, and ignoring autoboxing costs in loops.

1. Strings in Java: Immutability and Methods

flowchart TD
    A["String s1 = \"Hello\";"] --> B["String s2 = s1.concat(\"World\")"]
    B --> C["s1 unchanged: \"Hello\""]
    B --> D["s2 new: \"HelloWorld\""]
Immutability: Original string remains unchanged after concatenation
HelloHelloWorldHelloWorld123TOP
Stack of String objects created during repeated concatenation (inefficient)
H0e1l2l3o4
String 'Hello' as an immutable array of chars (memory state before/after concatenation)

1.1 What is a String?

A String in Java is a sequence of characters enclosed in double quotes ("..."). It is immutable, meaning once created, its value cannot be changed. Instead, new String objects are created for modifications.

String s1 = "Hello";  // String literal (stored in String pool)
String s2 = new String("Hello");  // Object in heap memory

Why immutability?

  • Thread safety (no race conditions in multi-threading).
  • Security (e.g., password storage).
  • Caching (interned strings in the pool).

1.2 Common String Methods

Method Description Example
length() Returns the length of the string. "Java".length() → 4
charAt(int index) Returns the character at the specified index. "Java".charAt(1) → 'a'
substring(int begin, int end) Extracts a substring. "Hello".substring(1, 3) → "el"
concat(String str) Concatenates two strings. "Hi".concat("!") → "Hi!"
equals(Object obj) Compares content (not reference). "abc".equals("abc") → true
equalsIgnoreCase(String s) Case-insensitive comparison. "Java".equalsIgnoreCase("java") → true
toUpperCase()/toLowerCase() Converts case. "Java".toLowerCase() → "java"
trim() Removes leading/trailing whitespace. " Hi ".trim() → "Hi"
split(String regex) Splits the string into an array using regex. "a,b,c".split(",") → ["a","b","c"]
replace(char old, char new) Replaces all occurrences of a character. "hello".replace('l', 'L') → "heLLo"
startsWith()/endsWith() Checks prefix/suffix. "file.txt".endsWith(".txt") → true

1.3 String Immutability: Performance Impact

Problem: Repeated concatenation in loops creates many temporary objects.

String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;  // Inefficient! Creates 1000 new String objects.
}

Solution: Use StringBuilder (mutable) for dynamic concatenation.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);  // Efficient! Modifies the same object.
}
String result = sb.toString();

1.4 String Pool and intern()

  • String Pool: A special memory area for string literals to avoid duplication.
  • intern(): Returns the canonical representation of a string (from the pool).
String s1 = new String("Java").intern();  // Stored in pool
String s2 = "Java";  // Also in pool
System.out.println(s1 == s2);  // true (same reference)

1.5 Real-World Example: Email Validation in eSewa

eSewa uses regex to validate user email inputs before processing payments. A typical regex pattern:

String emailRegex = "^[A-Za-z0-9+_.-]+@(.+)$";
Pattern pattern = Pattern.compile(emailRegex);
Matcher matcher = pattern.matcher("user@example.com");
System.out.println(matcher.matches());  // true

How it works:

  1. ^ asserts the start of the string.
  2. [A-Za-z0-9+_.-]+ matches alphanumeric characters and symbols.
  3. @ matches the literal "@".
  4. (.+)$ matches any characters after "@" until the end.

2. String Manipulation: Worked Example

Problem: Extract all digits from a string "Java123Coding456" and sum them. Solution:

String input = "Java123Coding456";
int sum = 0;
for (int i = 0; i < input.length(); i++) {
    char c = input.charAt(i);
    if (Character.isDigit(c)) {
        sum += Character.getNumericValue(c);
    }
}
System.out.println(sum);  // Output: 1+2+3+4+5+6 = 21

3. Wrapper Classes: Primitives to Objects

Java provides wrapper classes to convert primitives (int, double, etc.) to objects (e.g., Integer, Double). This is useful for:

  • Collections (e.g., ArrayList<Integer>).
  • Generic methods.
  • Autoboxing/unboxing.
010201—230340
Autoboxing: Primitives (10, 20, 30, 40) stored as Integer objects in a hash table (h(k) = k % 4)
Primitive Wrapper Class Example
int Integer Integer num = 10;
double Double Double d = 3.14;
char Character Character c = 'A';
boolean Boolean Boolean flag = true;

3.1 Autoboxing and Unboxing

  • Autoboxing: Automatic conversion of primitives to wrapper objects.
    int num = 10;  // Primitive
    Integer obj = num;  // Autoboxing (int → Integer)
    
  • Unboxing: Automatic conversion of wrapper objects to primitives.
    Integer obj = 20;
    int num = obj;  // Unboxing (Integer → int)
    

Warning: Autoboxing in loops can reduce performance due to object creation overhead.

// Inefficient (avoid in loops)
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
    numbers.add(i);  // Autoboxing happens here!
}

3.2 Key Wrapper Class Methods

Method Description Example
valueOf(String s) Converts a string to a wrapper object. Integer.valueOf("123") → 123
parseInt(String s) Converts a string to a primitive int. Integer.parseInt("123") → 123
toString() Converts a wrapper object to a string. Integer.toString(123) → "123"
compareTo(Object o) Compares two wrapper objects. Integer.compare(5, 3) → 1

3.3 Real-World Example: Ncell’s Bill Calculation

Ncell processes customer bills by converting string inputs (e.g., "500") to numeric values for calculations.

String usage = "500";  // User input (e.g., from a form)
int minutes = Integer.parseInt(usage);  // Convert to int
double bill = minutes * 0.10;  // Calculate bill
System.out.println("Your bill: Rs. " + bill);  // Rs. 50.0

4. Type Conversion in Java

4.1 Widening and Narrowing Conversion

Conversion Type Example Notes
Widening int → double Automatic (safe, no data loss).
Narrowing double → int Requires explicit casting (data loss).
double d = 10.5;
int i = (int) d;  // Narrowing (truncates to 10)

4.2 Parsing Strings to Primitives

Method Example Output
Integer.parseInt(String) Integer.parseInt("123") 123 (int)
Double.parseDouble(String) Double.parseDouble("3.14") 3.14 (double)
Boolean.parseBoolean(String) Boolean.parseBoolean("true") true (boolean)

Example: Convert user input to a numeric value.

Scanner scanner = new Scanner(System.in);
System.out.print("Enter age: ");
int age = Integer.parseInt(scanner.nextLine());  // Parses "25" → 25

4.3 Real-World Example: Daraz Order Processing

Daraz processes order quantities stored as strings (e.g., "5") and converts them to integers for inventory checks.

String quantityStr = "5";
int quantity = Integer.parseInt(quantityStr);  // Convert to int
if (quantity > 0) {
    System.out.println("Order placed for " + quantity + " items.");
} else {
    System.out.println("Invalid quantity!");
}

5. Regular Expressions (Regex) for Text Validation

Regex is a powerful tool for pattern matching in strings. Common use cases:

  • Email validation (^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$).
  • Phone number validation (^\+977\d{9}$ for Nepali numbers).
  • Password strength checks.
stateDiagram-v2
    [*] --> q1
    q1: ^[A-Za-z0-9+_.-]+@(.+)$
    q1 --> q2 : Match start
    q2: Check alphanumeric/symbols
    q2 --> q3 : @ found
    q3: Check domain
    q3 --> [*] : Valid email
    q3 --> q4 : Invalid
    q4 --> [*] : Reject
Regex validation flow for eSewa email format (simplified)

5.1 Regex Syntax

Metacharacter Description
. Matches any single character (except newline).
* Matches 0 or more of the preceding element.
+ Matches 1 or more of the preceding element.
? Matches 0 or 1 of the preceding element.
^ Matches the start of the string.
$ Matches the end of the string.
[] Matches any character inside the brackets (e.g., [a-z]).
` `
() Groups patterns.
\d Matches any digit ([0-9]).
\w Matches any word character ([a-zA-Z0-9_]).

5.2 Example: Validate Nepali Phone Number

String phoneRegex = "^\\+977\\d{9}$";  // Starts with +977, followed by 9 digits
String phone = "+9779812345678";
boolean isValid = phone.matches(phoneRegex);  // true

5.3 Real-World Example: Khalti’s Payment Reference Validation

Khalti validates payment references (e.g., "KHALTI12345") using regex:

String refRegex = "^KHALTI\\d{5}$";  // Must start with "KHALTI" followed by 5 digits
String ref = "KHALTI12345";
System.out.println(ref.matches(refRegex));  // true

6. Common Pitfalls and Best Practices

Pitfall Solution
NullPointerException Always check for null before calling methods (e.g., if (str != null)).
Incorrect casting Use instanceof to check types before casting.
Inefficient string concatenation Use StringBuilder for loops.
Regex errors Test patterns with tools like Regex101.
Autoboxing in loops Prefer primitives in performance-critical loops.

7. Exam Tip

  1. String Immutability:

    • Remember that + concatenation creates new objects. Use StringBuilder for dynamic strings.
    • Know the difference between == (reference comparison) and .equals() (content comparison).
  2. Wrapper Classes:

    • Distinguish between parseInt() (returns primitive) and valueOf() (returns wrapper object).
    • Understand autoboxing/unboxing but avoid overusing them in loops.
  3. Type Conversion:

    • Narrowing requires explicit casting and may lose data (e.g., double → int truncates decimals).
    • Always validate user input (e.g., try-catch for NumberFormatException).
  4. Regex:

    • Practice common patterns (email, phone, password).
    • Use matches() for full-string validation and find()/replaceAll() for partial matches.
  5. Code Examples:

    • Be ready to write short programs for:
      • String reversal.
      • Counting vowels/consonants.
      • Validating inputs (e.g., PIN codes).
      • Converting between primitives and wrappers.

flowchart TD
    A["Start"] --> B["Is input a String?"]
    B -->|"Yes"| C["Use String methods\n(e.g., substring, split)"]
    B -->|"No"| D["Is input a primitive?"]
    D -->|"Yes"| E["Use Wrapper classes\n(e.g., Integer.parseInt)"]
    D -->|"No"| F["Is input a wrapper object?"]
    F -->|"Yes"| G["Use unboxing\n(e.g., Integer obj → int num)"]
    F -->|"No"| H["Invalid input type"]
    C --> I["Return result"]
    E --> I
    G --> I
    H --> I

Flowchart: Handling different input types in Java.


classDiagram
    class String {
        +length() int
        +charAt(int) char
        +substring(int, int) String
        +equals(Object) boolean
        +toUpperCase() String
        +split(String) String[]
    }
    class StringBuilder {
        +append(String) StringBuilder
        +reverse() StringBuilder
        +toString() String
    }
    String -->|Immutable| String
    StringBuilder -->|Mutable| String

Class Diagram: String vs. StringBuilder.

In the real world

  • eSewa: Uses regex (^[A-Za-z0-9+_.-]+@(.+)$) to validate user email addresses before processing transactions, ensuring only properly formatted emails proceed to payment steps.
  • Khalti: Employs StringBuilder for dynamic concatenation of transaction IDs and amounts in bulk payment processing, improving performance over repeated String concatenation.
  • Nepali Banks (e.g., NMB, Global IME): Use Integer.parseInt() and Double.valueOf() to convert user-input strings (e.g., loan amounts, interest rates) into numeric types for calculations, with explicit checks for NumberFormatException.

Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 8.

Discussion

Loading…