Java Strings (Best Tutorial 2019)

Java 9 String

Java 9 String

Strings are one of the most commonly used data types in any programming language. They can be used for obtaining text from a keyboard, printing messages to a command line, and much more.

 

Given the fact that Strings are used so often, there have been many features added to the String object over time in order to make them easier to work with. After all, a String is an object in Java, so it contains methods that can be used to manipulate the contents of the String.

 

Strings are also immutable in Java, which means that their state cannot be changed or altered. This makes them a bit different to work with than some of the mutable, or changeable, data types.

 

It is important to understand how to properly make use of immutable objects, especially when attempting to change or assign different values to them.

 

This blog focuses on some of the most commonly used String methods and techniques for working with String objects. We also cover some useful techniques that are not inherent of String objects.

 

Compact Strings Java 9 String Enhancements

Since the Java language was introduced, Strings have been stored into an array of type UTF-16 char. The char array contains two bytes for each character, which eventually produces a large memory heap since Strings are used so often in our applications.

 

In Java 9, Strings are stored in an array of type byte, and stored characters are encoded either as ISO-8859-1/Latin-1 (one byte per character), or as UTF-16 (two bytes per character).

 

There is also an encoding flag on the char array, which is used to indicate which type of encoding is used for the String. These changes are otherwise known as compact Strings.

 

These changes do not affect the way in which we utilize Strings, nor do they alter the helper methods of the String class in any way. They may, however, significantly decrease the amount of memory used by an application.

 

Obtaining a Subsection of a String

Obtaining a Subsection

Problem: You would like to retrieve a portion of a String.

 

Solution

Use the substring() method to obtain a portion of the String between two different positions. In the solution that follows, a String is created and the various portions of the String are printed out using the substring() method.

public static void substringExample(){
String originalString = "This is the original String"; System.out.println(originalString.substring(0, originalString.length())); System.out.println(originalString.substring(5, 20)); System.out.println(originalString.substring(12));
}
Running this method would yield the following results:
This is the original String
is the original
original String

 


How It Works

String object

The String object contains many helper methods. One such method is substring(), which can be used to return portions of the String. There are two variations of the substring() method. One of them accepts a single argument, that being the starting index; and the other accepts two arguments: starting index and ending index.

 

Having two variations of the substring() method makes it seem as though the second argument is optional; if it is not specified, the length of the calling String is used in its place. It should be noted that indices begin with zero, so the first position in a String has the index of 0, and so on.

 

As you can see from the solution to this recipe, the first use of substring() prints out the entire contents of the String. This is because the first argument passed to the substring() method is 0, and the second argument passed is the length of the original String.

 

In the second example of substring(), an index of 5 is used as the first argument, and an index of 20 is used as the second argument.

 

This effectively causes only a portion of the String to be returned, beginning with the character in the String that is located in the sixth position, or index 5 because the first position has an index of 0; and ending with the character in the String that is located in the 20th position, the index of 19.

 

The third example specifies only one argument; therefore, the result will be the original String beginning with the position specified by that argument. Note The substring() method only accepts positive integer values. If you attempt to pass a negative value, an exception will be thrown.

 

Comparing Strings

Comparing Strings

Problem: An application that you are writing needs to have the ability to compare two or more String values.

 

Solution

Use the built-in equals(), equalsIgnoreCase(), compareTo(), and compareToIgnoreCase() methods to compare the values contained within the Strings.

 

The following is a series of tests using different String-comparison operations. As you can see, various if statements are used to print out messages if the comparisons are equal:

String one = "one";
String two = "two";
String var1 = "one";
String var2 = "Two";
String pieceone = "o";
String piecetwo = "ne";
Comparison is equal if (one.equals(var1)){
System.out.println ("String one equals var1 using equals");
}
Comparison is NOT equal
if (one.equals(two)){
System.out.println ("String one equals two using equals");
}
Comparison is NOT equal if (two.equals(var2)){
System.out.println ("String two equals var2 using equals");
}
Comparison is equal, but is not directly comparing String values using == if (one == var1){
System.out.println ("String one equals var1 using ==");
}
Comparison is equal
if (two.equalsIgnoreCase(var2)){
System.out.println ("String two equals var2 using equalsIgnoreCase");
}
System.out.println("Trying to use == on Strings that are pieced together");
String piecedTogether = pieceone + piecetwo;
// Comparison is equal
if (one.equals(piecedTogether)){
System.out.println("The Strings contain the same value using equals");
}
Comparison is NOT equal using == if (one == piecedTogether) {
System.out.println("The String contain the same value using == ");
}
// Comparison is equal
if (one.compareTo(var1) == 0){
System.out.println("One is equal to var1 using compareTo()");
}
Results in the following output:
String one equals var1 using equals
String one equals var1 using ==
String two equals var2 using equalsIgnoreCase
Trying to use == on Strings that are pieced together
The Strings contain the same value using equals
One is equal to var1 using compareTo()

 

How It Works

One of the trickier parts of using a programming language can come when attempting to compare two or more values, particularly String values. In the Java language, comparing Strings can be fairly straightforward, keeping in mind that you should not use the == for String comparison.

 

This is because the comparison operator (==) is used to compare references, not values of Strings. One of the most tempting things to do when programming with Strings in Java is to use the comparison operator, but you must not because the results can vary.

 

Note Java uses interning of Strings to speed up performance. This means that the JVM contains a table of interned Strings, and each time the intern() method is called on a String, a lookup is performed on that table to find a match. The interning returns a canonical representation of the String.

 

If no matching String resides within the table, the String is added to the table and a reference is returned. If the String already resides within the table, the reference is returned. Java will automatically intern String literals, and this can cause variation when using the == comparison operator.

 

In the solution to this recipe, you can see various different techniques for comparing String values. The equals() method is a part of every Java object. The Java String equals() method has been overridden so that it will compare the values contained within the String rather than the object itself.

 

As you can see from the following examples that have been extracted from the solution to this recipe, the equals() method is a safe way to compare Strings.

Comparison is equal if (one.equals(var1)){
System.out.println ("String one equals var1 using equals");
}
Comparison is NOT equal
if (one.equals(two)){
System.out.println ("String one equals two using equals");
}

 

The equals() method will first check to see whether the Strings reference the same object using the operator; it will return true if they do. If they do not reference the same object, equals() will compare each String character by character to determine whether the Strings being compared to each other contain exactly the same values.

 

What if one of the Strings has a different case setting than another? Do they still compare equal to each other using equals()? 

 

The answer is no, and that is why the equalsIgnoreCase() method was created. Comparing two values using equalsIgnoreCase() will cause each of the characters to be compared without paying attention to the case. The following examples have been extracted from the solution to this recipe:

Comparison is NOT equal if (two.equals(var2)){
System.out.println ("String two equals var2 using equals");
}
Comparison is equal
if (two.equalsIgnoreCase(var2)){
System.out.println ("String two equals var2 using equalsIgnoreCase");
}

 

The compareTo()and compareToIgnoreCase() methods perform a lexicographical comparison of the Strings. This comparison is based on the Unicode value of each character contained within the Strings. The result will be a negative integer if the String lexicographically precedes the argument, String.

 

The result will be a positive integer if the String lexicographically follows the argument String. The result will be zero if both Strings are lexicographically equal to each other. The following excerpt from the solution to this recipe demonstrates the compareTo() method:

// Comparison is equal
if (one.compareTo(var1) == 0){
System.out.println("One is equal to var1 using compareTo()");

 

Inevitably, many applications contain code that must compare Strings at some level. The next time you have an application that requires String comparison, consider the information discussed in this recipe before you write the code.

 

Trimming Whitespace

Trimming Whitespace

Problem: One of the Strings you are working with contains some whitespace on either end. You would like to get rid of that whitespace.

Solution

Use the String trim() method to eliminate the whitespace. In the following example, a sentence is printed including whitespace on either side. The same sentence is then printed again using the trim() method to remove the whitespace so that the changes can be seen.

String myString = " This is a String that contains whitespace. ";
System.out.println(myString);
System.out.println(myString.trim());
The output will print as follows:
This is a String that contains whitespace.
This is a String that contains whitespace.

 


How It Works

Regardless of how careful we are, whitespace can always become an issue when working with Strings of text. This is especially the case when comparing Strings against matching values.

 

If a String contains an unexpected whitespace character then that could be disastrous for a pattern-searching program. Luckily, the Java String object contains the trim() method that can be used to automatically remove whitespace from each end of any given String.

 

The trim() method is very easy to use. In fact, as you can see from the solution to this recipe, all that is required to use the trim() method is a call against any given String.

 

Because Strings are objects, they contain many helper methods, which can make them very easy to work with. After all, Strings are one of the most commonly used data types in any programming language…so they’d better be easy to use!

 

The trim() method returns a copy of the original String with all leading and trailing whitespace removed. If, however, there is no whitespace to be removed, the trim() method returns the original String instance. It does not get much easier than that!

 

Changing the Case of a String

 String

Problem

A portion of your application contains case-sensitive String values. You want to change all the Strings to uppercase before they are processed in order to avoid any case sensitivity issues down the road.

 

Solution

Make use of the toUpperCase() and toLowerCase() methods. The String object provides these two helper methods to assist in performing a case change for all of the characters in a given String.

For example, given the String in the following code, each of the two methods will be called:

String str = "This String will change case.";
System.out.println(str.toUpperCase());
System.out.println(str.toLowerCase());
The following output will be produced:
THIS STRING WILL CHANGE CASE.

this String will change case.

 

How It Works

To ensure that the case of every character within a given String is either upper or lowercase, use the toUpperCase() and toLowerCase() methods, respectively. There are a couple of items to note when using these methods.

 

First, if a given String contains an uppercase letter, and the toUpperCase() method is called against it, the uppercase letter is ignored. The same concept holds true for calling the toLowerCase() method. Any punctuation or numbers contained within the given String are also ignored.

 

There are two variations for each of these methods. One of the variations does not accept any arguments, while the other accepts an argument pertaining to the locale you wish to use. Calling these methods without any arguments will result in a case conversion using the default locale.

 

If you want to use a different locale, you can pass the desired locale as an argument, using the variation of the method that accepts an argument. For instance, if you want to use an Italian or French locale, you would use the following code:

System.out.println(str.toUpperCase(Locale.ITALIAN)); 
System.out.println(str.toUpperCase(new Locale("it","US"))); 
System.out.println(str.toLowerCase(new Locale("fr", "CA")));

 

Converting Strings to upper or lowercase using these methods can make life easy. They are also very useful for comparing Strings that are taken as input from an application. Consider the case in which a user is prompted to enter a username, and the result is saved into a String.

 

Now consider that later in the program that String is compared against all the usernames stored within a database to ensure that the username is valid. What happens if the person who entered the username types it with an uppercase first character?

 

What happens if the username is stored within the database in all uppercase? The comparison will never be equal. In such a case, a developer can use the toUpperCase() method to alleviate the problem.

 

Calling this method against the Strings that are being compared will result in a comparison in which the case is the same in both Strings.

 

Concatenating Strings

Concatenating Strings

Problem: There are various Strings that you want to combine into one.

Solution 1  If you want to concatenate Strings onto the end of each other, use the concat() method. The following example demonstrates the use of the concat() method:

String one = "Hello";
String two = "Java9";
String result = one.concat(" ".concat(two));
The result is this:
Hello Java9

 

Solution 2

Use the concatenation operator to combine the Strings in a shorthand manner. In the following example, a space character has been placed in between the two Strings:

String one = "Hello";
String two = "Java9";
String result = one + " " + two;
The result is this:
Hello Java9

 

Solution 3

Use StringBuilder or StringBuffer to combine the Strings. The following example demonstrates the use of

StringBuffer to concatenate two Strings:
String one = "Hello";
String two = "Java9";
StringBuffer buffer = new StringBuffer();
buffer.append(one).append(" ").append(two);
String result = buffer.toString();
System.out.println(result);
The result is this:
Hello Java9

 

How It Works

Java language

The Java language provides a couple of different options for concatenating Strings of text. Although none is better than the others, you may find one or the other to work better in different situations.

 

The concat() method is a built-in String helper method. It provides the ability to append one String onto the end of another, as demonstrated by solution 1 to this recipe.

 

The concat() method will accept any String value; therefore, you can explicitly type a String value to pass as an argument if you want. As demonstrated in solution 1, simply passing one String as an argument to this method will append it to the end of the String, which the method is called upon.

 

However, if you wanted to add a space character in between the two Strings, you could do so by passing a space character as well as the String you want to append as follows:

String result = one.concat(" ".concat(two));

 

As you can see, having the ability to pass any String or combination of Strings to the concat() method makes it very useful. Because all of the String helper methods actually return copies of the original String with the helper method functionality applied, you can pass Strings calling other helper methods to concat() (or any other String helper method) as well.

 

Consider that you want to display the text "Hello Java" rather than "Hello Java9". The following combination of String helper methods would allow you to do just that:

String one = "Hello";
String two = "Java9";
String result = one.concat(" ".concat(two.substring(0, two.length()-1)));


The concatenation operator (+) can be used to combine any two Strings. It is almost thought of as a shorthand form of the concat() method.

 

The last technique that is demonstrated in solution 3 to this example is the use of StringBuffer, which is a mutable sequence of characters, much like a String, except that it can be modified through method calls. The StringBuffer class contains a number of helper methods for building and manipulating character sequences.

 

In the solution, the append() method is used to append two String values. The append() method places the String that is passed as an argument at the end of the StringBuffer. For more information regarding the use of StringBuffer, refer to the online documentation at StringBuffer (Java SE 9 & JDK 9 ).

 

Converting Strings to Numeric Values

 Numeric Values

Problem: You want to have the ability to convert any numeric values that are stored as Strings into integers.

 

Solution 1

Use the Integer.valueOf() helper method to convert Strings to int data types. For example:

String one = "1";
String two = "2";
int result = Integer.valueOf(one) + Integer.valueOf(two);

 

As you can see, both of the String variables are converted into integer values. After that, they are used to perform an addition calculation and then stored into an int.

 

Note A technique known as autoboxing is used in this example. Autoboxing is a feature of the Java language that automates the process of converting primitive values to their appropriate wrapper classes.

 

For instance, this occurs when you assign an int value to an Integer. Similarly, unboxing automatically occurs when you try to convert in the opposite direction, from a wrapper class to a primitive. For more information on autoboxing, refer to the online documentation at Lesson: Numbers and Strings autoboxing.html.

 

Solution 2

Use the Integer.parseInt() helper method to convert Strings to int data types. For example:
String one = "1";
String two = "2";
int result = Integer.parseInt(one) + Integer.parseInt(two); System.out.println(result);

 

How It Works

 Integer class

The Integer class contains the valueOf() and parseInt() methods, which are used to convert Strings or int types into integers. There are two different forms of the Integer class’s valueOf() type that can be used to convert Strings into integer values. Each of them differs by the number of arguments that they accept.

 

The first valueOf() method accepts only a String argument. This String is then parsed as an integer value if possible, and then an integer holding the value of that String is returned. If the String does not convert into an integer correctly, then the method will throw a NumberFormatException.

 

The second version of Integer’s valueOf() method accepts two arguments: a String argument that will be parsed as an integer and an int that represents the radix that is to be used for the conversion.

 

Note Many of the Java type classes contain valueOf() methods that can be used for converting different types into that class’s type. Such is the case with the String class because it contains many different valueOf() methods that can be used for conversion.

 

For more information on the different valueOf() methods that the String class or any other type class contains, see the online Java documentation at http://docs.oracle. com/javase/9/docs

 

There are also two different forms of the Integer class’s parseInt() method. One of them accepts one argument: the String you want to convert into an integer. The other form accepts two arguments: the String that you want to convert to an integer and the radix.

 

The first format is the most widely used, and it parses the String argument as a signed decimal integer.

 

A NumberFormatException will be thrown if a parsable unsigned integer is not contained within the String. The second format, which is less widely used, returns an Integer object holding the value that is represented by the String argument in the given radix, given a parsable unsigned integer is contained within that String.

 

Note One of the biggest differences between parseInt() and valueOf() is that parseInt() returns an int and valueOf() returns an Integer from the cache.

 

Iterating Over the Characters of a String

Characters String

Problem: You want to iterate over the characters in a String of text so that you can manipulate them at the character level.

 

Solution

Use a combination of String helper methods to gain access to the String at a character level. If you use a String helper method within the context of a loop, you can easily traverse a String by character. In the following example, the String named str is broken down using the toCharArray() method.

String str = "Break down into chars";
System.out.println(str);
for (char chr:str.toCharArray()){
System.out.println(chr);
}
The same strategy could be used with the traditional version of the for loop. An index could be created that would allow access to each character of the String using the charAt() method.
for (int x = 0; x <= str.length()-1; x++){
System.out.println(str.charAt(x));
}

 

Note The first example using an example, using the traditional for toCharArray() generates a new character array. Therefore, the second loop might perform faster.

 

How It Works

String objects

String objects contain methods that can be used for performing various tasks. The solution to this recipe demonstrates a number of different String methods. The toCharArray() method can be called against a String in order to break the String into characters and then store those characters in an array.

 

This method is very powerful and it can save a bit of time when performing this task is required. The result of calling the toCharArray() method is a char[], which can then be traversed using an index.

 

Such is the case in the solution to this recipe. An enhanced for loop is used to iterate through the contents of the char[] and print out each of its elements.

 

The String length() method is used to find the number of characters contained within a String. The result is an int value that can be very useful in the context of a for loop, as demonstrated in the solution to this recipe.

 

In the second example, the length() method is used to find the number of characters in the String so that they can be iterated over using the charAt() method. The charAt() method accepts an int index value as an argument and returns the character that resides at the given index in the String.

 

Often the combination of two or more String methods can be used to obtain various results. In this case, using the length() and charAt() methods within the same code block provided the ability to break down a String into characters.

 

Finding Text Matches

Text Matches

Problem: You want to search a body of text for a particular sequence of characters.

 

Solution 1

Make use of regular expressions and the String matches() helper method to determine how many matches exist. To do this, simply pass a String representing a regular expression to the matches() method against any String you are trying to match. In doing so, the String will be compared with the String that matches() is being called upon.

 

Once evaluated, matches() will yield a boolean result, indicating whether it is a match. The following code excerpt contains a series of examples using this technique. The comments contained within the code explain each of the matching tests.

String str = "Here is a long String...let's find a match!"; // This will result in a "true" since it is an exact match
boolean result = str.matches("Here is a long String...let's find a match!"); System.out.println(result);
This will result iin "false" since the entire String does not match result = str.matches("Here is a long String...");
System.out.println(result);
str = "true";
This will test against both upper & lower case "T"...this will be TRUE result = str.matches("[Tt]rue");
System.out.println(result);
This will test for one or the other
result = str.matches("[Tt]rue|[Ff]alse]");
System.out.println(result);
This will test to see if any numbers are present, in this case the
person writing this String would be able to like any Java release! str = "I love Java 8!";
result = str.matches("I love Java [0-9]!"); System.out.println(result);
This will test TRUE as well...
str = "I love Java 7!";
result = str.matches("I love Java [0-9]!");
System.out.println(result);
The following will test TRUE for any language that contains
only one word for a name. This is because it tests for
any alphanumeric combination. Notice the space character
between the numeric sequence...
result = str.matches("I love .*[ 0-9]!");
System.out.println(result);
The following String also matches. str = "I love Jython 2.5.4!";
result = str.matches("I love .*[ 0-9]!");
System.out.println(result);

Each of the results printed out in the example will be true, with the exception of the second example because it does not match.

 

Solution 2

Use the regular expression Pattern and Matcher classes for a better-performing and more versatile matching solution than the String matches() method.

 

Although the matches() method will get the job done most of the time, there are some occasions in which you will require a more flexible way of matching. Using this solution is a three-step process:

  • \1.\ Compile a pattern into a Pattern object.
  • \2.\ Construct a Matcher object using the matcher() method on the Pattern.
  • \3.\ Call the matches() method on the Matcher.

 

In the following example code, the Pattern and Matcher technique is demonstrated:

String str = "I love Java 9!";
boolean result = false;
Pattern pattern = Pattern.compile("I love .*[ 0-9]!"); Matcher matcher = pattern.matcher(str); result = matcher.matches();
System.out.println(result);

The previous example will yield a TRUE value just like its variant that was demonstrated in solution 1.

 

How It Works

Regular expressions

Regular expressions are a great way to find matches because they allow patterns to be defined so that an application does not have to explicitly find an exact String match. They can be very useful when you want to find matches against some text that a user may be typing into your program.

 

However, they could be overkill if you are trying to match Strings against a String constant you have defined in your program because the String class provides many methods that could be used for such tasks.

 

Nevertheless, there will certainly come a time in almost every developer’s life when regular expressions can come in handy. They can be found in just about every programming language used today. Java makes them easy to use and understand.

 

Note Although regular expressions are used in many different languages today, the expression syntax for each language varies. For complete information regarding regular expression syntax, see the documentation online at Pattern (Java SE 9 & JDK 9 ).

 

The easiest way to make use of regular expressions is to call the matches() method on the String object. Passing a regular expression to the matches() method will yield a boolean result that indicates whether the String matches the given regular expression pattern or not. At this point, it is useful to know what a regular expression is and how it works.

 

A regular expression is a String pattern can be matched against other Strings in order to determine its contents. Regular expressions can contain a number of different patterns that enable them to be dynamic in that they can have the ability to match many different Strings that contain the same format.

 

For instance, in the solution to this recipe, the following code can match several different Strings:

result = str.matches("I love Java [0-9]!");

 

The regular expression String in this example is "I love Java [0-9]!", and it contains the pattern [0-9], which represents any number between 0 and 9. Therefore, any String that reads "I love Java" followed by the numbers 0 through 9 and then an exclamation point will match the regular expression String.

 

To see a listing of all the different patterns that can be used in a regular expression, see the online documentation available at the URL in the previous note.

 

A combination of Pattern and Matcher objects can also be used to achieve similar results as the String matcher() method. The Pattern object can be used to compile a String into a regular expression pattern. A compiled pattern can provide performance gains to an application if the pattern is used multiple times.

 

You can pass the same String–based regular expressions to the Pattern.compile() method as you would pass to the String matches() method. The result is a compiled Pattern object that can be matched against a String for comparison.

 

A Matcher object can be obtained by calling the Pattern object’s matcher() method against a given String.

 

Once a Matcher object is obtained, it can be used to match a given String against a Pattern using any of the following three methods, which each return a boolean value indicating a match.

 

The following three lines of solution 2 could be used as an alternate solution to using the Pattern.matches() method, minus the reusability of the compiled pattern:

Pattern pattern = Pattern.compile("I love .*[ 0-9]!"); Matcher matcher = pattern.matcher(str); result = matcher.matches();
The Matcher matches() method attempts to match the entire input String with the pattern.
The Matcher lookingAt() method attempts to match the input String to the pattern starting at the beginning.
The Matcher find() method scans the input sequence looking for the next matching sequence in the String.

 

In the solution to this recipe, the matches() method is called against the Matcher object in order to attempt to match the entire String. In any event, regular expressions can be very useful for matching Strings against patterns.

 

The technique used for working with the regular expressions can vary in different situations, using whichever method works best for the situation.

 

Replacing All Text Matches

sequence of characters

Problem: You have searched a body of text for a particular sequence of characters, and you are interested in replacing all matches with another String value.

 

Solution

Use a regular expression pattern to obtain a Matcher object; then use the Matcher object’s replaceAll() method to replace all matches with another String value. The example that follows demonstrates this technique:

String str = "I love Java 8! It is my favorite language. Java 8 is the "

"8th version of this great programming language."; Pattern pattern = Pattern.compile("[0-9]");

Matcher matcher = pattern.matcher(str); 
System.out.println("Original: " + str); 
System.out.println(matcher.matches()); 
System.out.println("Replacement: " + matcher.replaceAll("9"));

 

This example will yield the following results:

Original: I love Java 8! It is my favorite language. Java 8 is the 8th version of this great programming language.

Replacement: I love Java 9! It is my favorite language. Java 9 is the 9th version of this great programming language.

 

How It Works

The replaceAll() method of the Matcher object makes it easy to find and replace a String or a portion of String that is contained within a body of text.

 

In order to use the replaceAll() method of the Matcher object, you must first compile a Pattern object by passing a regular expression String pattern to the Pattern. compile() method. Use the resulting Pattern object to obtain a Matcher object by calling its matcher() method. The following lines of code show how this is done:

 

Pattern pattern = Pattern.compile("[0-9]");

Matcher matcher = pattern.matcher(str);

 

Once you have obtained a Matcher object, call its replaceAll() method by passing a String that you want to use to replace all the text that is matched by the compiled pattern. In the solution to this recipe, the String "9" is passed to the replaceAll() method, so it will replace all the areas in the String that match the "[0-9]" pattern.

 

Determining Whether a File Suffix Matches a Given String

Problem: You are reading a file from the server and you need to determine what type of file it is in order to read it properly.

 

Solution

Determine the suffix of the file by using the endsWith() method on a given file name. In the following example, assume that the variable filename contains the name of a given file, and the code is using the endsWith() method to determine whether filename ends with a particular String:

if(filename.endsWith(".txt")){
System.out.println("Text file");
} else if (filename.endsWith(".doc")){ System.out.println("Document file");
} else if (filename.endsWith(".xls")){ System.out.println("Excel file"); } else if (filename.endsWith(".java")){
System.out.println("Java source file"); } else {
System.out.println("Other type of file");
}


Given that a file name and its suffix are included in the filename variable, this block of code will read its suffix and determine what type of file the given variable represents.

 

How It Works

String object contains

As mentioned previously, the String object contains many helper methods that can be used to perform tasks. The String object’s endsWith() method accepts a character sequence and then returns a boolean value representing whether the original String ends with the given sequence. In the case of the solution to this recipe, the endsWith() method is used in an if block.

 

A series of file suffixes is passed to the endsWith() method to determine what type of file is represented by the filename variable. If any of the file name suffixes matches, a line is printed, stating what type of file it is.

 

Making a String That Can Contain Dynamic Information

 

Problem: You would like to generate a String that has the ability to contain a dynamic placeholder such that the String can change depending upon application data variations.

 

Solution 1

Utilize the String format() built-in method for generating a String containing placeholders for dynamic data.

 

The following example demonstrates a String that contains a dynamic placeholder that allows different data to be inserted into the same String. In the example, as the temperature variable changes, the String is dynamically altered.

public static void main(String[] args){
double temperature = 98.6;
String temperatureString = "The current temperature is %.1f degrees Farenheit.";
System.out.println(String.format(temperatureString, temperature));
temperature = 101.2;
System.out.println(String.format(temperatureString, temperature));
}
Output:
The current temperature is 98.6 degrees Farenheit.
The current temperature is 101.2 degrees Farenheit.

 

Solution 2

If you wish to print the contents of the String out, rather than store them for later use, the System. out.printf() method can be used to position dynamic values within a String.

 

The following example demonstrates the same concept like that in solution 1, except this time rather than using the String.format() method, a String is simply printed out, and the placeholders passed to the System.out.printf() method are replaced with the dynamic content at runtime.

public static void main(String[] args){
double temperature = 98.6;
System.out.printf("The current temperature is %.1f degrees Farenheit.\n", temperature);
temperature = 101.2;
System.out.printf("The current temperature is %.1f degrees Farenheit.", temperature);
}
Output:
The current temperature is 98.6 degrees Farenheit.
The current temperature is 101.2 degrees Farenheit.

 

How It Works

String content

When you require the use of dynamic String content, the format() utility can come in handy. The format() built-in method allows one to position a placeholder within a String, such that the placeholder will be replaced with dynamic content at runtime.

 

The format method accepts a String, along with a series of variables that will be used to displace the placeholders within the String with dynamic content at runtime.

 

The placeholders must be designated specifically for the type of content with which they will be displaced. The table contains a list of each placeholder or conversion type for the String.format() function.

 

String.format() Conversion Types

Conversion Content Type

b boolean
h hex
s String
c Unicode character
d decimal integer
o octal integer
x hexadecimal integer
e floating point decimal number in computerized scientific notation
f floating point decimal number
g floating point using computerized scientific notation or decimal format, depending
upon the precision and value after rounding
a hexadecimal floating-point number with significand and exponent
t date/time
n platform-specific line separator

Each placeholder must begin with a % character to denote that it is a placeholder within the String. The placeholder can also contain flags, width, and precision indicators to help format the dynamic value appropriately. The following format should be used to build each placeholder:

 

%[flags][width][.precision]conversion_indicator

 

The second solution demonstrates how to utilize the System.out.printf() method, which accepts the same arguments as the System.format() method.

 

The main difference between the two is that the System. out.printf() method is handy for printing formatted content. If your application requires the need to store a formatted value, you will be more likely to use the String.format() method.

 

Numbers and Dates

Dates

Numbers play a significant role in many applications. As such, it is helpful to know how to use them correctly within the context of the work that you are trying to perform.

 

This blog helps you understand how to perform some of the most basic operations with numbers, and it also provides insight on performing advanced tasks such as working with currency. There are a number of ways to work with currency, and this blog will focus on a couple of them.

 

Dates are also important as they can be used for many purposes within an application. In Java 8, the new Date-Time package called java.time was introduced. The Date-Time API uses the calendar defined in ISO-8601 as the default.

 

Therefore, the calendar is based on the Gregorian calendar system, and in this blog, you will learn how to work with date, time, and time zone data. The Date-Time API adheres to several design principles, in that it’s clear, fluent, immutable, and extensible.

 

The API uses a clear language that is concise and very well defined. It is also very fluent, so code dealing with date-time data is easy to read and understand. Most of the classes within the Date-Time API are immutable, so in order to alter a date-time object, you must create a modified copy of the original.

 

As such, many of the methods in the date-time classes are named accordingly, such as of() and with(), so that you know you are creating a copy rather than altering the original. Lastly, the new Date-Time API can be extended in many cases, allowing it to be useful in many contexts.

 

The Date-Time API is made up of a rich set of classes, providing solutions that were rather difficult to achieve in previous APIs. Even though there are many different classes, most of them contain a similar set of methods, so the same principles can be utilized throughout all of the date and time units.

 

As mentioned previously, the Date-Time API is fluent; therefore, each of its classes is located in a clearly marked package.

 

Date-Time API Packages

Time

Package Description

java.time The core classes of the API. These classes are used for working with date-time data
based on the ISO-8601 standard. These classes are immutable and thread-safe.
java.time.chrono The API for using calendar systems other than ISO-8601.
java.time.format Classes for formatting date-time data.
java.time.temporal Extended API that allows interpolations between date-time classes.
java.time.zone Classes supporting time zone data.

This blog presents a brief overview of some commonly used date-time features. If you will be performing significant work with dates and times, you should read the Date-Time API documentation that is available online in addition to this blog.

 

Rounding Float and Double Values to Integers

 

Problem: You need to be able to round floating-point numbers or doubles in your application to Integer values.

 

Solution: Use one of the java.lang.Math round() methods to round the number into the format you require. The Math class has two methods that can be used for rounding floating-point numbers or Double values. The following code demonstrates how to use each of these methods:

public static int roundFloatToInt(float myFloat){ return Math.round(myFloat);

}

public static long roundDoubleToLong(double myDouble){ return Math.round(myDouble);

}


The first method, roundFloatToInt(), accepts a floating-point number and uses the java.lang.Math class to round that number to an Integer. The second method, roundDoubleToLong(), accepts a Double value and uses the java.lang.Math class to round that Double to a Long.

 

How It Works

The java.lang.Math class contains plenty of helper methods to make our lives easier when working with numbers. The round() methods are no exception as they can be used to easily round floating-point or double values. One version of the java.lang.Math round() method accepts a float as an argument.

 

It will round the float to the closest int value, with ties rounding up. If the argument is Not a Number (NaN), then a zero will be returned. When arguments that are positive or negative infinity are passed into round(), a result equal to the value of Integer.MAX_VALUE or Integer.MIN_VALUE, respectively, will be returned.

 

The second version of the java.lang.Math round() method accepts a double value. The double value is rounded to the closest long value, with ties rounding up. Just like the other round(), if the argument is NaN, a zero will be returned.

 

Similarly, when arguments that are positive or negative infinity are passed into round(), a result equal to the value of Long.MAX_VALUE or Long.MIN_VALUE, respectively, will be returned.

 

Note NaN, POSITIVE_INFINITY, and NEGATIVE_INFINITY are constant values defined within the Float and Double classes. NaN (Not a Number) is an undefined or unrepresentable value.

For example, a NaN value can be produced by dividing 0.0f by 0.0f.

 

The values represented by POSITIVE_INFINITY and NEGATIVE_INFINITY refer to values that are produced by operations that generate such extremely large or negative values of a particular type (floating-point or double) that they cannot be represented normally.

 

For instance, 1.0/0.0 or –1.0/0.0 would produce such values.

 

Formatting Double and Long Decimal Values

Problem: You need to be able to format double and long numbers in your application.

Solution

Use the DecimalFormat class to format and round the value to the precision your application requires. In the following method, a double value is accepted and a formatted String value is printed:

public static void formatDouble(double myDouble){
NumberFormat numberFormatter = new DecimalFormat("##.000");
String result = numberFormatter.format(myDouble);
System.out.println(result);
}
For instance, if the double value passed into the formatDouble() method is 345.9372, the following will be the result:
345.937
Similarly, if the value .7697 is passed to the method, the following will be the result:
.770

Each of the results is formatted using the specified pattern and then rounded accordingly.

 

How It Works

Format class

The DecimalFormat class can be used along with the NumberFormat class to round and/or format double or long values. NumberFormat is an abstract class that provides the interface for formatting and parsing numbers.

 

This class provides the ability to format and parse numbers for each locale and obtain formats for currency, percentage, integers, and numbers.

 

By itself, the NumberFormat class can be very useful as it contains factory methods that can be used to obtain formatted numbers. In fact, little work needs to be done in order to obtain a formatted String.

 

For example, the following code demonstrates calling some factory methods on the NumberFormat class:

Obtains an instance of NumberFormat class NumberFormat format = NumberFormat.getInstance();
Format a double value for the current locale String result = format.format(83.404); System.out.println(result);
Format a double value for an Italian locale
result = format.getInstance(Locale.ITALIAN).format(83.404); System.out.println(result);
Parse a String into a Number try {
Number num = format.parse("75.736"); System.out.println(num);
} catch (java.text.ParseException ex){ System.out.println(ex);
}

 

To format using a pattern, the DecimalFormat class can be used along with NumberFormat. In the solution to this recipe, you saw that creating a new DecimalFormat instance by passing a pattern to its constructor would return a NumberFormat type. This is because DecimalFormat extends the NumberFormat class.

 

Because the NumberFormat class is abstract, DecimalFormat contains all the functionality of NumberFormat, plus added functionality for working with patterns.

 

Therefore, it can be used to work with different formats from the locales just as you have seen in the previous demonstration. This provides the ultimate flexibility when working with double or long formatting.

 

As mentioned previously, the DecimalFormat class can take a String-based pattern in its constructor. You can also use the applyPattern() method to apply a pattern to the Format object after the fact.

 

Each pattern contains a prefix, numeric part, and suffix, which allow you to format a particular decimal value to the required precision and include leading digits and commas as needed. The symbols used to build patterns are displayed in Table.

 

Each of the patterns also contains a positive and negative subpattern. These two subpatterns are separated by a semicolon (;) and the negative subpattern is optional. If there is no negative subpattern present, the localized minus sign is used.

 

For instance, a complete pattern example would be ###,##0.00;(###,##0.00).

 

The DecimalFormat class provides enough flexibility to format double and long values for just about every situation.

 

Comparing int Values

Problem: You need to compare two or more int values.

int Values

Solution 1

Use the comparison operators to compare integer values against one another. In the following example, three int values are compared against each other, demonstrating various comparison operators:

int int1 = 1;
int int2 = 10;
int int3 = -5;
System.out.println(int1 == int2); // Result: false
System.out.println(int3 == int1); // Result: false
System.out.println(int1 == int1); // Result: true
System.out.println(int1 > int3); // Result: true
System.out.println(int2 < int3); // Result: false

As you can see, comparison operators will generate a boolean result.

 

Solution 2

Use the Integer.compare(int,int) method to compare two int values numerically. The following lines could compare the same int values that were declared in the first solution:

System.out.println("Compare method -> int3 and int1: " + Integer.compare(int3, int1)); // Result -1

System.out.println("Compare method -> int2 and int1: " + Integer.compare(int2, int1)); // Result 1


How It Works

Perhaps the most commonly used numeric comparisons are against two or more int values. The Java language makes it very easy to compare an int using the comparison operators.

 

The second solution to this recipe demonstrates the integer compare() method that was added to the language in Java 7.

This static method accepts two int values and compares them, returning a 1 if the first int is greater than the second, a 0 if the two int values are equal, and a -1 if the first int value is less than the second.

 

To use the Integer.compare() method, pass two int values as demonstrated in the following code:

Integer.compare(int3, int1));

Integer.compare(int2, int1));

 

Just like in your math lessons at school, these comparison operators will determine whether the first integer is equal to, greater than, or less than the second integer. Straightforward and easy to use, these comparison operators are most often seen within the context of an if-statement.

 

Comparing Floating-Point Numbers

Point Numbers

Problem: You need to compare two or more floating-point values in an application.

Solution 1

Use the Float object’s compareTo() method to perform a comparison of one float against another. The following example shows the compareTo() method in action:

Float float1 = new Float("9.675");
Float float2 = new Float("7.3826");
Float float3 = new Float("23467.373");
System.out.println(float1.compareTo(float3)); // Result: -1
System.out.println(float2.compareTo(float3)); // Result: -1
System.out.println(float1.compareTo(float1)); // Result: 0
System.out.println(float3.compareTo(float2)); // Result: 1

 

The result of calling the compareTo() method is an integer value. A negative result indicates that the first float is less than the float that it is being compared against. A zero indicates that the two float values are equal. Lastly, a positive result indicates that the first float is greater than the float that it is being compared against.

 

Solution 2

Use the Float class compare() method to perform the comparison. The following example demonstrates the use of the Float.compare(float, float) method.

System.out.println(Float.compare(float1, float3)); // Result: -1
System.out.println(Float.compare(float2, float3)); // Result: -1
System.out.println(Float.compare(float1, float1)); // Result: 0
System.out.println(Float.compare(float3, float2)); // Result: 1

 

How It Works

The most useful way to compare two float objects is to use the compareTo() method. This method will perform a numeric comparison against the given float objects. The result will be an integer value indicating whether the first float is numerically greater than, equal to, or less than the float that it is compared against.

 

If a float value is NaN, it is considered to be equal to other NaN values or greater than all other float values. Also, a float value of 0.0f is greater than a float value of -0.0f.

 

An alternative to using compareTo() is the compare() method, which is also native to the Float class. The compare() method was introduced in Java 1.4, and it is a static method that compares two float values in the same manner as compareTo().

 

It only makes the code read a bit differently. The format for the compare() method is as follows:

Float.compare(primitiveFloat1, primitiveFloat2)
The compare() method shown will actually make the following call using compareTo():
new Float(float1).compareTo(new Float(float2));
In the end, the same results will be returned using either compareTo() or compare().

 

Calculating Monetary Values

Monetary Values

Problem

You are developing an application that requires the use of monetary values and you are not sure which data type to use for storing and calculating currency values.

 

Solution 1

Use the BigDecimal data type to perform a calculation on monetary values. Format the resulting calculations using the NumberFormat.getCurrencyInstance() helper method. In the following code, three monetary values are calculated using a handful of the methods that are part of the BigDecimal class.

 

The resulting calculations are then converted into double values and formatted using the NumberFormat class. First, take a look at how these values are calculated:

BigDecimal currencyOne = new BigDecimal("25.65"); BigDecimal currencyTwo = new BigDecimal("187.32"); BigDecimal currencyThree = new BigDecimal("4.86"); BigDecimal result = null; String printFormat = null;
// Add all three values
result = currencyOne.add(currencyTwo).add(currencyThree);
Convert to double and send to formatDollars(), returning a String printFormat = formatDollars(result.doubleValue()); System.out.println(printFormat);
Subtract the first currency value from the second
result = currencyTwo.subtract(currencyOne); printFormat = formatDollars(result.doubleValue()); System.out.println(printFormat);
Next, let’s take a look at the formatDollars() method that is used in the code. This method accepts a double value and performs formatting on it using the NumberFormat class based on the U.S. locale. It then returns a String value representing currency:
public static String formatDollars(double value){
NumberFormat dollarFormat = NumberFormat.getCurrencyInstance(Locale.US); return dollarFormat.format(value);
}

 

As you can see, the NumberFormat class allows for currency to be formatted per the specified locale. This can be very handy if you are working with an application that deals with currency and have an international scope.

$217.83

$161.67

 

Solution 2

Utilize the Java Money API, which was the focus of JSR 354, to perform monetary calculations.

Note The Java Money API was developed under JSR 354 https://jcp.org/en/jsr/detail?id=354.

 

It was originally intended for completion and inclusion with Java 9. However, the JSR was completed quite a bit early and contains no dependencies on the Java 9 codebase. Therefore, the Java Money API can be used with older versions of Java as well, such as Java 8, and it is available on Github at JavaMoney.

 

The following example demonstrates how to perform currency calculations and formatting using the.Java Money API.

MonetaryAmount amount1 = Money.of(25.65, Monetary.getCurrency("USD")); MonetaryAmount amount2 = Money.of(187.32, Monetary.getCurrency("USD")); MonetaryAmount amount3 = Money.of(4.86,Monetary.getCurrency("USD"));
MonetaryAmount result = null;
result = amount1.add(amount2).add(amount3);
MonetaryAmountFormat printFormat = MonetaryFormats.getAmountFormat(
AmountFormatQuery.of(Locale.US));
System.out.println("Sum of all: " + printFormat.format(result));
result = amount2.subtract(amount1);
System.out.println("Subtract amount1 from amount 2: " + printFormat.format(result));

 

How It Works

Many people attempt to use different number formats when working with currency. While it might be possible to use any type of numeric object to work with currency, the BigDecimal class was added to the language in Java 5 to help satisfy the requirements of working with currency values, among other things.

 

We will begin by explaining how to utilize BigDecimal for currency calculations, as it is the classic procedure, and then we’ll take a look at the Java Money API.

 

Perhaps the most useful feature of the BigDecimal class is that it provides control over rounding. This is essentially why such a class is so useful for working with currency values.

 

The BigDecimal class provides an easy API for rounding values, and also makes it easy to convert to double values, as the solution to this recipe demonstrates.

 

Note The use of BigDecimal for working with monetary values is a good practice. However, it can come at some performance expense. Depending on the application and performance requirements, it might be worth using Math.round() to achieve basic rounding if performance becomes an issue.

 

To provide specific rounding with the BigDecimal class, you should use a MathContext object or the RoundingMode enumeration values. In either case, such precision can be omitted by using a currency-formatting solution such as the one demonstrated in the solution example.

 

BigDecimal objects have mathematical implementations built into them, so performing such operations is an easy task. The arithmetic operations that you can use are described in Table.

 

Method Description

Method

  • add() Adds one BigDecimal object value to another.
  • subtract() Subtracts one BigDecimal object value from another.
  • multiply() Multiplies the value of one BigDecimal object by another.
  • abs() Returns the absolute value of the given BigDecimal object value.
  • pow(n) Returns the BigDecimal to the power of n; the power is computed to unlimited precision.

 

After performing the calculations you require, call the doubleValue() method on the BigInteger object to convert and obtain a double. You can then format the double using the NumberFormat class for currency results.

 

The Java Money API began as JSR 354, in an effort to make it easier to work with currency in the Java language. The API provides a truly significant change to the language, as it finally allows one to treat currency in a standard manner, rather than utilizing the BigDecimal in various ways.

 

The payoff of using the Java Money API can be huge since it can make code easier to read and understand and provide a monetary result rather than a result that must be coerced into a currency value.

 

In solution 2, the same currency values are used to demonstrate a handful of calculation exercises. The standard types for currency in the API is a MonetaryAmount.

 

In the solution, you can see that there are three MonetaryAmount objects, and each of them represent different values in dollars and cents using the USD currency.

 

To obtain the values that are stored into the MonetaryAmount objects, the Money implementation class is used to parse the value that is given to it, and then return a MonetaryAmount type of the specified currency type. The Money class stores number values using BigDecimal.

 

The MonetaryAmount interface provides a number of methods that can be utilized for performing operations against the stored value, comparing against other amounts, precision, and so forth.

 

 Specifically, in the solution, you can see that the add() method accepts another MonetaryAmount, and it is used to add the value passed into the original MonetaryAmount. Another such method is subtracted (), which subtracts the value passed from the original.

 

The solution also provides information about formatting monetary values. The MonetaryFormats factory can be used to obtain formats specific to the desired locale. The resulting MonetaryAmountFormat pattern can then be applied to a MonetaryAmount to change the presentation of the value accordingly.

 

Randomly Generating Values

Generating Values

Problem: An application that you are developing requires the use of randomly generated numbers.

 

Solution 1

Use the java.util.Random class to help generate the random numbers. The Random class was developed for the purpose of generating random numbers for a handful of the Java numeric data types. This code demonstrates the use of Random to generate such numbers:

Create a new instance of the Random class Random random = new Random();

Generates a random Integer

int myInt = random.nextInt();
Generates a random Double value double myDouble = random.nextDouble();
// Generates a random float
float myFloat = random.nextFloat();
Generates a random Gaussian double
mean 0.0 and standard deviation 1.0
from this random number generator's sequence. double gausDouble = random.nextGaussian();
Generates a random Long
long myLong = random.nextLong();
// Generates a random boolean
boolean myBoolean = random.nextBoolean();

 

Solution 2

Make use of the Math.random() method. This will produce a double value that is greater than 0.0, but less than 1.0. The following code demonstrates the use of this method:

double rand = Math.random();

 

How It Works

The java.util.Random class uses a 48-bit seed to generate a series of pseudorandom values. As you can see from the example in the solution to this recipe, the Random class can generate many different types of random number values based on the given seed.

 

By default, the seed is generated based on a calculation derived from the number of milliseconds that the machine has been active.

 

However, the seed can be set manually using the Random setSeed() method. If two Random objects have the same seed, they will produce the same results.

 

It should be noted that there are cases in which the Random class might not be the best choice for generating random values.

 

For instance, if you are attempting to use a thread-safe instance of java.util.Random, you might run into performance issues if you’re working with many threads.

 

In such a case, you might consider using the ThreadLocalRandom class instead. To see more information regarding ThreadLocalRandom, see the documentation at http://docs.oracle.com/javase/9/docs/api/java/util/ concurrent/ThreadLocalRandom.html.

 

Similarly, if you require the use of a cryptographically secure Random object, consider the use of SecureRandom. Documentation regarding this class can be found at Oracle JDK 9 Documentation docs/api/java/security/SecureRandom.html.

 

The java.util.Random class comes in very handy when you need to generate a type-specified random value. Not only is it easy to use but it also provides a wide range of options for return type.

 

Another easy technique is to use the Math.random() method, which produces a double value that is within the range of 0.0 to 1.0, as demonstrated in solution 2.

 

Both techniques provide a good means of generating random values. However, if you need to generate random numbers of a specific type, java.util.Random is the best choice.

 

Obtaining the Current Date Without Time

Problem: You are developing an application for which you would like to obtain the current date, not including the time, to display on a form.

Solution

Make use of the Date-Time API to obtain the current date. The LocalDate class represents an ISO calendar in the year-month-day format. The following lines of code capture the current date and display it:

LocalDate date = LocalDate.now();

System.out.println("Current Date:" + date);


How It Works

The Date-Time API makes it easy to obtain the current date, without including other information such as time. To do so, import the java.time.LocalTime class and call on its now() method.

 

The LocalTime class cannot be instantiated, as it is immutable and thread-safe. A call to the now() method returns another LocalDate object, containing the current date in the year-month-day format.

 

Another version of the now() method accepts a java.time.Clock object as a parameter and returns the date based on that clock. For instance, the following lines of code demonstrate how to obtain a Clock that represents the system time:

Clock clock = Clock.systemUTC();

LocalDate date = LocalDate.now(clock);

 

In previous releases, there were other ways to obtain the current date, but usually, the time came with the date and then formatting had to be done to remove the unneeded time digits. The new java.time. The localdate class makes it possible to work with dates separate from times.

 

Obtaining a Date Object Given Date Criteria

Problem: You want to obtain a date object, given a year-month-day specification.

Solution

Invoke the LocalDate.of() method for the year, month, and day for which you want to obtain the object.

 

For example, suppose that you want to obtain a date object for a specified date in November of 2000. You could pass that date criteria to the LocalDate.of() method, as demonstrated in the following lines of code:

LocalDate date = LocalDate.of(2000, Month.NOVEMBER, 11);

System.out.println("Date from specified date: " + date);

Here’s the result:

Date from specified date: 2000-11-11

 

How It Works

The LocalDate.of() method accepts three values as parameters. Those parameters represent the year, month, and day. The year parameter is always treated as an int value. The month parameter can be presented as an int value, which corresponds to an enum that represents the month.

 

The Month enum will return an int value for each month, with JANUARY returning a 1 and DECEMBER returning a 12. Therefore, Month.NOVEMBER returns an 11.

 

A Month object could also be passed as the second parameter instead of as an int value. Lastly, the day of the month is specified by passing an int value as the third parameter to the of() method.

 

Note For more information regarding the Month enum, see the online documentation at http://download.java.net/jdk9/docs/api/java/time/Month.html.

 

Obtaining a Year-Month-Day Date Combination

Problem: You would like to obtain the year, year-month, or month of a specified date.

Solution 1

To obtain the year-month of a specified date, use the java.time.YearMonth class. This class is used to represent the month of a specific year. In the following lines of code, the YearMonth object is used to obtain the year and month of the current date and another specified date.

YearMonth yearMo = YearMonth.now();
System.out.println("Current Year and month:" + yearMo); 
YearMonth specifiedDate = YearMonth.of(2000, Month.NOVEMBER); 
System.out.println("Specified Year-Month: " + specifiedDate);

Here’s the result:

Current Year and month:2014-12

Specified Year-Month: 2000-11

 

Solution 2

To obtain the month-day for the current date or a specified date, simply make use of the java.time.MonthDay class. The following lines of code demonstrate how to obtain a month-day combination.

MonthDay monthDay = MonthDay.now(); System.out.println("Current month and day: " + monthDay);
MonthDay specifiedDate = MonthDay.of(Month.NOVEMBER, 11); System.out.println("Specified Month-Day: " + specifiedDate);
Here’s the result:
Current month and day: --12-14
Specified Month-Day: --11-11

 

Note that by default, MonthDay does not return a very useful format.

 

How It Works

API

The Date-Time API includes classes that make it easy to obtain the information that your application requires for a date. Two of those are the YearMonth and MonthDay classes.

 

The YearMonth class is used to obtain the date in year-month format. It contains a few methods that can be used to obtain the year-month combination.

 

As demonstrated in the solution, you can call the now() method to obtain the current year-month combination. Similar to the LocalDate class, YearMonth also contains an of() method that accepts a year in int format, and a number that represents the month of the year. In the solution, the Month enum is used to obtain the month value.

 

Similar to the YearMonth class, MonthDay obtains the date in a month-day format. It also contains a few different methods for obtaining the month-day combination.

 

Solution 2 demonstrates two such techniques: Obtaining the current month-day combination by calling the now() method and using the of() method to obtain a month-day combination for a specified date.

 

The of() method accepts an int value for the month of the year as its first parameter, and for the second parameter, it accepts an int value indicating the day of the month.

 

Obtaining and Calculating Times Based on the Current Time

Current Time

Problem

You would like to obtain the current time so that it can be used to stamp a given record. You would also like to perform calculations based on that time.

 

Solution

Use the LocalTime class, which is part of the new Date-Time API, to obtain and display the current time. In the following lines of code, the LocalTime class is demonstrated.

LocalTime time = LocalTime.now();
System.out.println("Current Time: " + time);
Once the time has been obtained, methods can be called against the LocalTime instance to achieve the desired result. In the following lines of code, there are some examples of using the LocalTime methods:
// atDate(LocalDate): obtain the local date and time
LocalDateTime ldt = time.atDate(LocalDate.of(2011,Month.NOVEMBER,11)); System.out.println("Local Date Time object: " + ldt);
of(int hours, int min): obtain a specific time LocalTime pastTime = LocalTime.of(1, 10);
compareTo(LocalTime): compare two times. Positive
return value returned if greater
System.out.println("Comparing times: " + time.compareTo(pastTime));
getHour(): return hour in int value (24-hour format) int hour = time.getHour(); System.out.println("Hour: " + hour);
isAfter(LocalTime): return Boolean comparison
System.out.println("Is local time after pastTime? " + time.isAfter(pastTime));
minusHours(int): Subtract Hours from LocalTime LocalTime minusHrs = time.minusHours(5); System.out.println("Time minus 5 hours: " + minusHrs);
plusMinutes(int): Add minutes to LocalTime LocalTime plusMins = time.plusMinutes(30); System.out.println("Time plus 30 mins: " + plusMins);
Here are the results:
Current Time: 22:21:08.419
Local Date Time object: 2011-11-11T22:21:08.419
Comparing times: 1
Hour: 22
Is local time after pastTime? true
Time minus 5 hours: 17:21:08.419
Time plus 30 mins: 22:51:08.419


How It Works

Sometimes it is necessary to obtain the current system time. The LocalTime class can be used to obtain the current time by calling its now() method. Similarly to the LocalDate class, the LocalTime.now() method can be called to return a LocalTime object that is equal to the current time.

 

The LocalTime class also contains several methods that can be utilized to manipulate the time. The examples contained in the solution provide a brief overview of the available methods.

 

Let’s take a look at a handful of examples to provide some context for how the LocalTime methods are invoked. To obtain a LocalTime object set to a specific time, invoke the LocalTime.of(int, int) method, passing int parameters representing the hour and minute.

of(int hours, int min): obtain a specific time LocalTime pastTime = LocalTime.of(1, 10);

The atDate(LocalDate) instance method is used to apply a LocalDate object to a LocalTime instance, returning a LocalDateTime object.

LocalDateTime ldt = time.atDate(LocalDate.of(2011,Month.NOVEMBER,11));

 

There are several methods that can be used for obtaining portions of the time. For instance, the getHour(), getMinute(), getNano(), and getSecond() methods can be used to return those specified portions of the LocalTime object.

int hour = time.getHour();

int min = time.getMinute();

int nano = time.getNano();

int sec = time.getSecond();

 

Several comparison methods are also available for use. For example, the compareTo(LocalTime) method can be used to compare one LocalTime object to another. isAfter(LocalTime) can be used to determine if the time is after another, and isBefore(LocalTime) is used to specify the opposite. If calculations are needed, several methods are available, including:

minus(long amountToSubtract, TemporalUnit unit)
minus(TemporalAmount amount)
minusHours(long)
minusMinutes(long)
minusNanos(long)
minusSeconds(long)
plus(long amountToAdd, TemporalUnit unit)
plus(TemporalAmount amount)
plusHours(long)
plusMinutes(long)
plusNanos(long)
plusSeconds(long)

To see all of the methods contained in the LocalTime class, see the online documentation at LocalTime (Java SE 9 & JDK 9 ). Obtaining and Using the Date and Time Together

 

Problem: In your application, you want to display not only the current date but also the current time.

Date-Time

Solution 1

Make use of the LocalDateTime class, which is part of the new Date-Time API, to capture and display the current date and time. The LocalDateTime class contains a method named now(), which can be used to obtain the current date and time together. The following lines of code demonstrate how to do so:

 

LocalDateTime ldt = LocalDateTime.now(); System.out.println("Local Date and Time: " + ldt);

 

The resulting LocalDateTime object contains both the date and time, but no time zone information. The LocalDateTime class also contains additional methods that provide options for working with date-time data.

 

For instance, to return a LocalDateTime object with a specified date and time, pass parameters of int type to the LocalDateTime.of() method, as follows:

 

Obtain the LocalDateTime object of the date 11/11/2000 at 12:00 LocalDateTime ldt2 = LocalDateTime.of(2000, Month.NOVEMBER, 11, 12, 00); 

The following examples demonstrate a handful of the methods that are available in a LocalDateTime object:

Obtain the month from LocalDateTime object Month month = ldt.getMonth();
int monthValue = ldt.getMonthValue(); System.out.println("Month: " + month); System.out.println("Month Value: " + monthValue);
Obtain day of Month, Week, and Year
int day = ldt.getDayOfMonth(); DayOfWeek dayWeek = ldt.getDayOfWeek(); int dayOfYr = ldt.getDayOfYear(); System.out.println("Day: " + day); System.out.println("Day Of Week: " + dayWeek); System.out.println("Day of Year: " + dayOfYr);
// Obtain year
int year = ldt.getYear();
System.out.println("Date: " + monthValue + "/" + day + "/" + year);
int hour = ldt.getHour();
int minute = ldt.getMinute();
int second = ldt.getSecond();
System.out.println("Current Time: " + hour + ":" + minute + ":" + second);
// Calculation of Months, etc.
LocalDateTime currMinusMonths = ldt.minusMonths(12);
LocalDateTime currMinusHours = ldt.minusHours(10);
LocalDateTime currPlusDays = ldt.plusDays(30);
System.out.println("Current Date and Time Minus 12 Months: " + currMinusMonths);
System.out.println("Current Date and Time MInus 10 Hours: " + currMinusHours);
System.out.println("Current Date and Time Plus 30 Days:" + currPlusDays);
Here’s the result:
Day: 28
Day Of Week: SATURDAY
Day of Year: 332
Date: 11/28/2015
Current Time: 10:23:8
Current Date and Time Minus 12 Months: 2014-11-28T10:23:08.399
Current Date and Time MInus 10 Hours: 2015-11-28T00:23:08.399
Current Date and Time Plus 30 Days:2015-12-28T10:23:08.399

 

Solution 2

If you only need to obtain the current date without going into calendar details, use the java.util.Date class to generate a new Date object. Doing so will generate a new Date object that is equal to the current system date.

 

In the following code, you can see how easy it is to create a new Date object and obtain the current date:

Date date = new Date();

System.out.println("Using java.util.Date(): " + date);

System.out.println("Getting time from java.util.Date(): " + date.getTime());

 

The result will be a Date object that contains the current date and time taken from the system that the code is run on, including the time zone information, as shown following listing. The time is the number of milliseconds since January 1, 1970, 00:00:00 GMT.

 

Using java.util.Date(): Sat Nov 28 10:23:08 CST 2015

Getting time from java.util.Date(): 1448727788454

 

Solution 3

If you need to be more precise regarding the calendar, use the java.util.Calendar class. Although working with the Calendar class will make your code longer, the results are more granular than using a java.util.Date. The following code demonstrates just a handful of the capabilities of using this class to obtain the current date:

Calendar gCal = Calendar.getInstance();

 

Month is based upon a zero index, January is equal to 0, so we need to add one to the month for it to be in a standard format

int month = gCal.get(Calendar.MONTH) + 1;int day = gCal.get(Calendar.DATE); int yr = gCal.get(Calendar.YEAR);
String dateStr = month + "/" + day + "/" + yr; System.out.println(dateStr);
int dayOfWeek = gCal.get(Calendar.DAY_OF_WEEK);
Print out the integer value for the day of the week System.out.println(dayOfWeek);
int hour = gCal.get(Calendar.HOUR);
int min = gCal.get(Calendar.MINUTE);
int sec = gCal.get(Calendar.SECOND);
// Print out the time
System.out.println(hour + ":" + min + ":" + sec);
Create new DateFormatSymbols instance to obtain the String
value for dates
DateFormatSymbols symbols = new DateFormatSymbols();
String[] days = symbols.getWeekdays();
System.out.println(days[dayOfWeek]);
// Get crazy with the date!
int dayOfYear = gCal.get(Calendar.DAY_OF_YEAR); System.out.println(dayOfYear);
Print the number of days left in the year System.out.println("Days left in " + yr + ": " + (365-dayOfYear));
int week = gCal.get(Calendar.WEEK_OF_YEAR);
Print the week of the year System.out.println(week);

 

As demonstrated by this code, it is possible to obtain more detailed information regarding the current date when using the Calendar class. The results of running the code will look like the following:

11/28/2015
7
10:28:26
Saturday
332
Days left in 2015: 33
48

Note Although the java.util.The calendar provides a robust technique for obtaining precise Date/Time information, the preferred solution as of Java 8 is to make use of the Java Date-Time API.

 

How It Works

calendar date

Many applications require the use of the current calendar date. It is often also necessary to obtain the current time. There are different ways to do that, and the solution to this recipe demonstrates three of them.

 

The Date-Time API includes a LocalDateTime class that enables you to capture the current date and time by invoking its now() method.

 

A specified date and time can be obtained by specifying the corresponding int and Month type parameters when calling LocalDateTime.of().

 

There are also a multitude of methods available for use via a LocalDateTime instance, such as getHours(), getMinutes(), getNanos(), and getSeconds(), which allow for finer-grained control of the date and time. An instance of LocalDateTime also contains methods for performing calculations, conversions, comparisons, and more.

 

For brevity, all of the methods are not listed here, but for further information; refer to the online documentation at http://docs.oracle.com/javase/9/docs/api/java/time/LocalDateTime.html.

 

Solution 1 to this recipe demonstrates the use of the LocalDateTime, showcasing how to perform calculations and obtain portions of the date and time for further use.

 

By default, the java.util.Date class can be instantiated with no arguments to return the current date and time. The Date class can also be used to return the current time of day via the getTime() method.

 

As mentioned in the solution, the getTime() method returns the number of milliseconds since January 1, 1970, 00:00:00 GMT, represented by the Date object that is in use.

 

There are several other methods that can be called against a Date object with regard to breaking down the current date and time into more granular intervals. For instance, the Date class has the methods getHours(), getMinutes(), getSeconds(), getMonth(), getDay(), getTimezoneOffset(), and getYear().

 

However, it is not advisable to use any of these methods, with the exception of getTime(), because each has been deprecated by the use of the java.time.

 

LocalDateTime and the java.util.Calendar get() method. When a method or class is deprecated, that means it should no longer be used because it might be removed in some future release of the Java language.

 

However, a few of the methods contained within the Date class have not been tagged as deprecated, so the Date class will most likely be included in future releases of Java.

 

The methods that were left intact include the comparison methods after(), before(), compareTo(), setTime(), and equals(). Solution 2 to this recipe demonstrates how to instantiate a Date object and print out the current date and time.

 

As mentioned previously, the Date class has many methods that have become deprecated and should no longer be used. In solution 3 of this recipe, the java.util.Calendar class is demonstrated as one successor for obtaining much of this information. The Calendar class was introduced in JDK 1.1, at which time many of the Date methods were deprecated.

 

As you can see from solution 3, the Calendar class contains all the same functionality that is included in the Date class, except the Calendar class is much more flexible. The Calendar class is actually a class that contains methods that are used for converting between a specific time and date and manipulating the calendar in various ways.

 

The Calendar, as demonstrated in solution 3, is one such class that extends the Calendar class and therefore provides this functionality. The Calendar class has gained a few new methods in Java 8. The new methods in java.util.

 

New Methods for java.util.Calendar in Java 8

 

Method Name Description

  • getAvailableCalendarTypes() Returns unmodifiable set containing all supported calendar types.
  • getCalendarType() Returns the calendar type of this calendar.
  • toInstant() Converts to an instant.

 

For some applications, the Date class will work fine. For instance, the Date class can be useful when working with timestamps. However, if the application requires detailed manipulation of dates and times then it is advisable to use a LocalDateTime or the Calendar class, which both include all the functionality of the Date class and more features as well.

 

All solutions to this recipe are technically sound; choose the one that best suits the needs of your application.

 

Obtaining a Machine Timestamp

Problem: You need to obtain a machine-based timestamp from the system.

 

Solution

Utilize an Instant class, which represents the start of a nanosecond on the timeline based on machine time. In the following example, an Instant is used to obtain the system timestamp. The Instant is also utilized in other scenarios, such as when calculating different dates based on the Instant.

public static void instants(){
Instant timestamp = Instant.now(); System.out.println("The current timestamp: " + timestamp);
//Now minus three days
Instant minusThree = timestamp.minus(3, ChronoUnit.DAYS); System.out.println("Now minus three days:" + minusThree);
ZonedDateTime atZone = timestamp.atZone(ZoneId.of("GMT")); System.out.println(atZone);
Instant yesterday = Instant.now().minus(24, ChronoUnit.HOURS); System.out.println("Yesterday: " + yesterday);
}


Here is the result:

The current timestamp: 2015-11-28T16:21:42.197Z Now minus three days:2015-11-25T16:21:42.197Z 2015-11-28T16:21:42.197Z[GMT] Yesterday: 2015-11-27T16:21:42.273Z

 

How It Works

The Date-Time API introduces a new class named Instant, which represents the start of a nanosecond on the timeline in machine-based time. Being based on machine time, the value for an Instant count from the EPOCH (January 1, 1970, 00:00:00Z).

 

Any values prior to the EPOCH are negative, and after the EPOCH the values are positive. The Instant class is perfect for obtaining a machine timestamp, as it includes all pertinent date and time information to the nanosecond.

 

An Instant class is static and immutable, so to obtain the current timestamp, the now() method can be called. Doing so returns a copy of the current Instant. The Instant also includes conversion and calculation methods, each returning copies of the Instant or other types.

 

In the solution, the now() method returns the current timestamp, and then a couple of examples follow, showing how to perform calculations and obtain information on the Instant.

 

The Instant is an important new feature in Java 8, as it makes it easy to work with current time and date data. The other date and time classes, such as LocalDateTime, are useful as well. However, the Instant is the most accurate timestamp as it’s based on nanosecond accuracy.

 

Converting Dates and Times Based on the Time Zone

Problem

The application you are developing has the potential to be utilized throughout the world. In some areas of the application, static dates and times need to be displayed, rather than the system date and time. In such cases, those static dates and times need to be converted to suit the particular time zone in which the application user is currently residing.

 

Solution

The Date-Time API provides the proper utilities for working with time zone data via the Time Zone and Offset classes. In the following scenario, suppose that the application is working with reservations for rental vehicles. You could rent a vehicle in one-time zone and return it in another.

 

The following lines of code demonstrate how to print out an individual’s reservation in such a scenario.

 

The following method, named scheduleReport, accepts LocalDateTime objects representing check-in and check-out date/time, along with ZoneIds for each. This method could be used by an airline to print time-zone information for a particular flight.

public static void scheduleReport(LocalDateTime checkOut, ZoneId checkOutZone, LocalDateTime checkIn, ZoneId checkInZone){
ZonedDateTime beginTrip = ZonedDateTime.of(checkOut, checkOutZone); System.out.println("Trip Begins: " + beginTrip);
// Get the rules of the check out time zone
ZoneRules checkOutZoneRules = checkOutZone.getRules(); System.out.println("Checkout Time Zone Rules: " + checkOutZoneRules);
//If the trip took 4 days
ZonedDateTime beginPlus = beginTrip.plusDays(4); System.out.println("Four Days Later: " + beginPlus);
// End of trip in starting time zone
ZonedDateTime endTripOriginalZone = ZonedDateTime.of(checkIn, checkOutZone); ZonedDateTime endTrip = ZonedDateTime.of(checkIn, checkInZone);
int diff = endTripOriginalZone.compareTo(endTrip); String diffStr = (diff >= 0) ? "NO":"YES";
System.out.println("End trip date/time in original zone: " + endTripOriginalZone);
System.out.println("End trip date/time in check-in zone: " + endTrip ); System.out.println("Original Zone Time is less than new zone time? " +
diffStr );
ZoneId checkOutZoneId = beginTrip.getZone();
ZoneOffset checkOutOffset = beginTrip.getOffset();
ZoneId checkInZoneId = endTrip.getZone();
ZoneOffset checkInOffset = endTrip.getOffset();
System.out.println("Check out zone and offset: " + checkOutZoneId + checkOutOffset);
System.out.println("Check in zone and offset: " + checkInZoneId + checkInOffset);
}

 

Here is the result:

Trip Begins: 2015-12-13T13:00-05:00[US/Eastern]

Checkout Time Zone Rules: ZoneRules[currentStandardOffset=-05:00]

Four Days Later: 2015-12-17T13:00-05:00[US/Eastern]

End trip date/time in original zone: 2015-12-18T10:00-05:00[US/Eastern] End trip date/time in check-in zone: 2015-12-18T10:00-07:00[US/Mountain] Original Zone Time is less than new zone time? YES Check out zone and offset: US/Eastern-05:00

Check in zone and offset: US/Mountain-07:00

 

How It Works

Time zones add yet another challenge for developers, and the Java Date-Time API provides an easy facet for working with them. The Date-Time API includes a java.time.zone package, which contains a number of classes that can assist in working with time zone data.

 

These classes provide support for time zone rules, data, and resulting gaps and overlap in the local timeline that is typically the result of daylight savings conversions. The classes that make up the zone package are outlined in Table.

 Table               Time Zone Classes

Class Name                     Description

ZoneId             Specifies zone identifier and is used for conversions.
ZoneOffset       Specifies a time zone offset from Greenwich/UTC time.
ZonedDate       Time A date-time object that also handles the time zone data with time zone
offset from        Greenwich/UTC time.
ZoneRules        Rules defining how a zone offset varies for a specified time zone.
ZoneRulesProvider Provider of time zone rules to a particular system.
ZoneOffset        Transition Transition between two offsets by a discontinuity in the local timeline.
ZoneOffset        TransitionRule Rules expressing how to create a transition.

 

Starting with the most fundamental time zone class, ZoneId, each time zone contains a particular timezone identifier. This identifier can be useful for assigning a particular time zone to a date-time.

 

In the solution, the ZoneId is used to calculate any differences between two time zones. ZoneId identifies the rules that should be used for converting, based on a particular offset, either fixed or geographical region-based.

 

For more details on ZoneId, see the documentation at http://docs.oracle.com/javase/9/docs/api/java/ time/ZonedDateTime.html.

 

ZonedDateTime is an immutable class that is utilized for working with date-time and time zone data together. This class represents an object, much like LocalDateTime, that includes the ZoneId. It can be used to express all facets of a date, including year, month, day, hours, minutes, seconds, Nanos, and time zone.

 

The class contains a bevy of methods that are useful for performing calculations, conversions, and so on. For brevity, the methods that are contained in ZonedDateTime are not listed here, but you can read about each of them in the documentation at ZonedDateTime (Java SE 9 & JDK 9 ).

 

ZoneOffset specifies a time zone offset from Greenwich/UTC time. You can find the offset for a particular time zone by invoking the ZonedDateTime.getOffset() method. The ZoneOffset class includes methods that make it easy to break down an offset into different time units.

 

For instance, the get total seconds() method returns the total of hours, minutes, and seconds fields as a single offset that can be added to a time.

 

Refer to the online documentation for more information at Moved javase/9/docs/api/java/time/ZoneOffset.html.

 

There are many rules that can be defined for determining how zone offset varies for a single time zone. The ZoneRules class is used to define these rules for a zone. For instance, ZoneRules can be called on to specify or determine if daylight savings time is a factor.

 

An Instant or LocalDateTime can also be passed to ZoneRules methods such as getOffset() and getTransition() to return ZoneOffset or ZoneOffsetTransition. For more information on ZoneRules, refer to the online documentation at ZoneRules (Java SE 9 & JDK 9 ).

 

Another time zone class that is used often is ZoneOffsetTransition. This class model the transition between the spring and autumn offsets as a result of daylight savings time changes. It is used to determine if there is a gap between transitions, obtaining the duration of a transition, and so on. For more information on

 

ZoneOffsetTransition, see the online documentation at Java SE 9 & JDK 9 java/time/zone/ZoneOffsetTransition.html.

 

ZoneRulesProvider, ZoneOffsetTransitionRule, and other classes are typically not utilized as often as others for working with dates and time zones. These classes are useful for managing configuration of time zone rules and transitions.

 

Note The classes within the java.time.zone package is significant, in that there is a multitude of methods that can be invoked on each class. This recipe provides a primer for getting started, with only the basics of time zone usage. For more detailed information, see the online documentation.

 

Comparing Two Dates

Problem: You want to determine if one date is greater than another.

 

Solution: Utilize one of the compareTo() methods that are part of the Date-Time API classes. In the following solution, two LocalDate objects are compared and an appropriate message is displayed.

public static void compareDates(LocalDate ldt1, LocalDate ldt2) {
int comparison = ldt1.compareTo(ldt2);
if (comparison > 0) {
System.out.println(ldt1 + " is larger than " + ldt2); } else if (comparison < 0) {
System.out.println(ldt1 + " is smaller than " + ldt2); } else {
System.out.println(ldt1 + " is equal to " + ldt2);
}
}
Similarly, there are convenience methods for use when performing date comparison. Specifically, the methods isAfter(), isBefore(), and isEqual() can be used to compare in the same manner as compareTo(), as seen in the following listing.
public static void compareDates2(LocalDate ldt1, LocalDate ldt2){ if(ldt1.isAfter(ldt2)){
System.out.println(ldt1 + " is after " + ldt2);
} else if (ldt1.isBefore(ldt2)){ System.out.println(ldt1 + " is before " + ldt2);
} else if (ldt1.isEqual(ldt2)){ System.out.println(ldt1 + " is equal to " + ldt2);
}
}

 

How It Works

Many of the Date-Time API classes contain a method that is used to compare two different date-time objects. In the solution to this example, the LocalDate.compareTo() method is used to determine if one LocalDate object is greater than another.

 

The compareTo() method returns a negative int value if the first LocalDate is greater than the second, a zero if they are equal, and a positive number if the second LocalDate is greater than the first.

 

Each of the date-time classes that contain a compareTo() has the same outcome. That is, an int value is returned indicating if the first object is greater than, less than, or equal to the second. Each of the classes that contain the compareTo() method is listed here:

Duration
LocalDate
LocalDateTime
LocalTime
Instant
MonthDay
OffsetDateTime
Year
YearMonth

 

As seen in the second listing, the isAfter(), isBefore(), and isEqual() methods can also be used for comparison purposes.

 

These methods return a boolean to indicate the comparison results. While the outcome of these methods can be used to perform date comparison in much the same way as compareTo(), they can make code a bit easier to read.

Recommend