Skip to main content

Wrapper Classes

Primitive Wrappers

Primitive data types represent data only, they are unable to provide methods for operating.

\rightarrow Wrapper classes. Each primitive type has a wrapper class:

  • byte, short, int, long: Byte, Short, Integer, Long
  • float, double: Float, Double
  • char: Character
  • boolean: Boolean
int valA = 10;
Integer valB = 10;
  • valA is a primitive type, so it directly stores value of 10.
  • valB is a reference type, it holds a reference, that reference refers to an instance of Integer class.
valA [10]
valB [] ------> (20)

Implementation

E.g.

  • int is a primitive value, it is stored on the object field or on the stack, takes up 4 bytes directly (| 4 byte int |).
  • Integer is boxed numerics, it is the whole object lies on the heap, so it needs a pointer, takes up 24 bytes or 64bit JVM (| Object Header | 4 byte int | Padding |).

Converting

int valA = 10;
Integer valB = 10;
Integer valC = valA; // boxing
int valD = valB; // unboxing
  • Boxing: convert from primitive type to a wrapper class.
  • Unboxing: convert from a wrapper class to a primitive type.

The wrappers have methods to convert, but Java compiler helps to do these conversions automatically with auto(un)boxing. Instead of doing this,

int aPrimitive = 42;
Integer anObject = new Integer(aPrimitive);
myList.add(anObject); // suppose this method only accepts object parameter

you can just do this:

int aPrimitive = 42;
myList.add(aPrimitive); // auto: myList.add(new Integer(aPrimitive));

Integer anObject = aPrimitive; // auto: = new Integer(aPrimitive);
int anotherPrimitive = anObject; // auto: = anObject.intValue();

Strings

String Class

String name = "Tu";
String greeting = "Hello " + name;
greeting += " good to see you!";

String variables do not directly hold the string value, it hold a reference to the instance of string.

String are immutable. So when we change the value, it actually creates a entirely new instance of the string.

This is how above code work under the hood:

name  --------  | T | u |
| H | e | l | l | o |
| H | e | l | l | o | | T | u |
greeting ----- | H | e | l | l | o | | T | u | | g | o | o | d | | t | o | s | e | e | | y | o | u | ! |

Equality

Equality operator == check if both string variables reference the same string instance.

To perform character-by-character comparision, use s.equal().

String s1 = "I love";
s1 += " you";
String s2 = "I";
s2 += " love you";

if( s1 == s2 ) { // false, this compare reference
}
if (s1.equals(s2)) { // true, compare value
}

Interning string

Interning a string will canonicalize value and enable reliable ==.

// above example
String s3 = s1.intern();
String s4 = s2.intern();

if ( s3 == s4 ){ // true
}

What it actually does:

s1 --- abc
s2 --- abc

s3 --- abc (first time, search for interned version of s1, if no, create)
/
s4 / (next time, only need to reference to that interned version)

We only should use intern when we compare strings frequently.

Methods

OperationMethods
Lengthlength
Create new string(s) from existingconcat replace toLowerCase toUpperCase trim split
Extract substringcharAt substring
Test substringcontains endsWith startsWith indexOf lastIndexOf
Comparisonequals equalsIgnoreCase isEmpty compareTo compareToIgnoreCase
Formattingformat
String for non-stringvalueOf

Conversions

StringBuilder

Strings are immutable. So we have StringBuilder, it provides mutable string buffer.

StringBuilder itself is not a string, we need to convert it to a string.

String title = "student";
int age = 18;

StringBuilder sb = new StringBuilder(34);
sb.append("I am a ");
sb.append(title);
sb.append(" at ");
sb.append(age);

String str = sb.toString(); // "I am a student at 18"

String major = "software engineering";
int pos = sb.indexOf(" student");
sb.insert(pos, major);
sb.insert(pos, " ");
String message = sb.toString(); // "I am a software engineering student at 18"

Formatting