In this post, I will cover a some of the Core Java APIs (String, StringBuilder, Wrapper classes, and Date Time API) that we are responsible for Java 8 Programmer I exam.
I think the first thing that we need to know is immutability. String class is immutable, meaning that the state of the string literal cannot be modified after it is created. Once a string literal is created, it is located into the string pool for future use.
Let’s consider the following example. The first line created a string literal “string pool”, and it is assigned to “x”. At the second line, the same literal is assigned to “y”, but a new object is not allocated in memory. Since both references points to the same memory location, “x == y” is true.
In the next example, the “string” and “pool” are different literals, which are allocated to different addresses in memory. In this case, the references are not the same. Therefore, “x == y” is false.
A string created with StringBuilder class is mutable, which can be modified after it is created. When we created a StringBuilder object, a new object is created in heap. We can manipulate the content of the same object. Consider following example:
There is only one object created at the first line. The append operation is performed on the existing object.
String vs StringBuilder
I saw many tricky questions, which mix String and StringBuilder functions, in practice tests. For example, following example checks if you know the append method doesn’t belong to String class.
String s = new String("tricky"); s.append(" question"); // String class doesn't have append method System.out.println(s);
According to the book, OCA Oracle Certified Associate Java SE 8 Programmer I Study Guide, we need to know the most used functions in both classes for the exam. The first 4 functions are common, the rest are different.
|toLowerCase() and toUpperCase()||append()|
|equals() and equalsIgnoreCase()||insert()|
|startsWith() and endsWith()||delete() and deleteCharAt()|
Java provides wrapper classes for each primitive data types. We need to know following table. Remember that Character class doesn’t have parse and valueOf functions.
|Primitive type||Wrapper class|
Passing invalid value to wrapper functions causes NumberFormatException
int x = Integer.parseInt(“1”); // valid
int x = Integer.parseInt(“sdf”); // runtime exception
Autoboxing and Unboxing
Unboxing: Converting from wrapper to primitive type.
- public static boolean parseBoolean(String s)
Autoboxing: Converting from primitive type to wrapper class.
Date and Time APIs
All classes in the Date Time API
- are in java.time package
- are immutable (we need to reassign values to the reference)
- are thread-safe (good for multi-threaded environments)
We must use static methods since they have private constructors, which prevents you to create an instance of a class.
LocalDate d = new LocalDate(); // compile error. use LocalDate.of() instead
Manipulating Dates and Times (LocalDate, LocalTime, LocalDateTime)
LocalDate contains just a date (2015-01-20) , no time methods
LocalDate date1 = LocalDate.of(2017, Month.MAY, 28); LocalDate date2 = LocalDate.of(2017, 5, 28); LocalDate date1 = LocalDate.of(2017, Month.MAY, 28);
LocalTime contains just a time (13:11:10.03) , no date methods
LocalDate date2 = LocalDate.of(2017, 5, 12); LocalTime time1 = LocalTime.of(3, 25); // hour and minute LocalTime time2 = LocalTime.of(8, 25, 20); // + seconds LocalTime time3 = LocalTime.of(7, 25, 20, 200); // + nanoseconds
LocalDateTime contains both a date and time but no time zone 2017-02-06T13:12:14.10
LocalDateTime dateTime = LocalDateTime.of(2017, Month.MAY, 20, 6, 15, 30); //or LocalDate date = LocalDate.of(2017, Month.MAY, 28); LocalTime time = LocalTime.of(6, 15); LocalDateTime dateTime = LocalDateTime.of(date1, time1);
Adding to a date (plusDays, plusWeeks…)
The date and time classes are immutable. This means that we need to remember to assign the results of these methods to a reference variable so they are not lost.
LocalDate date = LocalDate.of(2017, Month.MAY, 20); System.out.println(date); // 2017-05-20 Output format (year–month-day) date = date.plusDays(2); System.out.println(date); // 2017-05-22 date = date.plusWeeks(1); System.out.println(date); // 2017-05-29 date = date.plusMonths(1); System.out.println(date); // 2017-02-28 date = date.plusYears(5); System.out.println(date); // 2059-02-28
Go backward in time (minusDays,minusHours, minusSeconds)
LocalDate date = LocalDate.of(2017, Month.MAY, 28); LocalTime time = LocalTime.of(5, 15); LocalDateTime dateTime = LocalDateTime.of(date, time); System.out.println(dateTime); // 2017-05-28T05:15 dateTime = dateTime.minusDays(1); System.out.println(dateTime); // 2017-05-19T05:15 dateTime = dateTime.minusHours(10); System.out.println(dateTime); // 2017-05-18T19:15 dateTime = dateTime.minusSeconds(30); System.out.println(dateTime); // 2017-05-18T19:14:30
We can use method chaining with LocaleDate, LocalTime, and LocalDateTime classes.
LocalDate date2 = LocalDate.of(2007, Month.MAY, 20); LocalTime time = LocalTime.of(4, 10); LocalDateTime dateTime = LocalDateTime.of(date2, time).minusDays(2).minusHours(1).minusSeconds(3);
Periods (ofYears, ofMonths…)
Period class models a quantity or amount of time in terms of years, months and days.
Period annually = Period.ofYears(1); // every 1 year Period quarterly = Period.ofMonths(3); // every 3 months Period everyThreeWeeks = Period.ofWeeks(3); // every 3 weeks Period everyOtherDay = Period.ofDays(2); // every 2 days Period everyYearAndAWeek = Period.of(1, 0, 7); // every year and 7 days
Be careful with method chaining when creating a Period. The first line in the following example obtains a
Period representing every week, not every year and 7 weeks.
Period wrong = Period.ofYears(1).ofWeeks(1); // every week Period right= Period.of(1, 0, 7); // every year and 7 weeks
You can add period to LocaeDateTime and LocaleDate but LocalTime. Adding period to LocalTime results in “UnsupportedTemporalTypeException”.
LocalDate date = LocalDate.of(2017, 5, 28); LocalTime time = LocalTime.of(6, 5); LocalDateTime dateTime = LocalDateTime.of(date, time); Period period = Period.ofMonths(1); System.out.println(date.plus(period)); // 2017-06-28 System.out.println(dateTime.plus(period)); // 2017-06-28T06:05 System.out.println(time.plus(period)); // UnsupportedTemporalTypeException
Formatting Dates and Times
You are only responsible for SHORT and MEDIUM predifined formats for the exam.
SHORTis completely numeric, such as
MEDIUMis longer, such as
Jan 12, 1952
DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); System.out.println(shortDateTime.format(dateTime)); // 1/20/20 System.out.println(shortDateTime.format(date)); // 1/20/20 System.out.println(shortDateTime.format(time)); // UnsupportedTemporalTypeException. Time cannot be formatted as a date
DateTimeFormatter shortF = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); DateTimeFormatter mediumF = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); System.out.println(shortF.format(dateTime)); // 1/20/20 10:33 AM System.out.println(mediumF.format(dateTime)); // May 28, 2017 11:12:34 AM
DateTimeFormatter.ofPattern(“MMMM dd, yyyy, hh:mm”);
DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm"); System.out.println(dateTime.format(f)); // May 20, 2010, 11:12 DateTimeFormatter f = DateTimeFormatter.ofPattern("hh:mm"); // We can only use this formatter with objects containing times f.format(dateTime); // ok f.format(date); // throw an exception. f.format(time); // ok
Parsing Dates and Times (_____.parse())
DateTimeFormetter f = DateTimeFormatter.ofPattern(“MM dd yyyy”); LocalDate date = LocalDate.parse("08 11 2017", f); LocalTime time = LocalTime.parse("11:22"); System.out.println(date); // 2017-08-11 System.out.println(time); // 11:22