To upgrade Java knowledge that stopped at "1.4" I am learning about Java7,8,9. This time, I will only describe what I investigated about the functions added in "8".
Optional It is now possible to explicitly indicate whether the return value may contain null. You can also set what to do if there is no value when you retrieve it.
public Optional<String> getGyunyu(String name) {
Map<String, String> gyunyu = new HashMap<>();
gyunyu.put("milk", "コーヒーmilk");
return Optional.ofNullable(gyunyu.get(name));
}
Optional<String> gyunyu = getGyunyu("Tea");
System.out.println(gyunyu.orElse("Not milk")); // 「Not milk」が出力される
--ofNullable (T value): Generate Optional. If the value is not null, it returns an Optional that describes the value, otherwise it returns an empty Optional. --orElse (T other): Returns a value if it exists, otherwise returns other.
You can also check for the existence of a value by using the ʻisPresent ()` method.
Optional<String> gyunyu = getGyunyu("Tea");
if (!gyunyu.isPresent()) {
System.out.println("Not milk");
}
In this case, I feel that it is not much different from ʻif (return value == null)`, but if it is null, the value should be retaken. It seems that it can be used when you want to perform additional processing.
interface interface can now have an implementation. By describing the default keyword, you can describe the method that has the implementation.
Gyunyu.java
public interface Gyunyu {
public default void print() {
System.out.println("milk");
}
}
Coffee.java
public class Coffee implements Gyunyu {
//I haven't overridden the print method but I don't get a compile error
}
Gyunyu gyunyu = new Coffee();
gyunyu.print();
Create a Milk
interface that inherits the Gyunyu
interface and
If you implement it in the ʻIchigoclass and call the
print ()` method,
Milk.java
public interface Milk extends Gyunyu {
public default void print() {
System.out.println("milk");
}
}
Ichigo.java
public class Ichigo implements Milk {
}
Gyunyu gyunyu = new Ichigo();
gyunyu.print(); //"Milk" is output
The method closest to the class calling the method (in this case the Milk
interfaceprint ()
) is executed.
Date and Time API
You can get the current date and time by using the now ()
method.
//No time zone information
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.getYear());
System.out.println(localDateTime.getMonthValue());
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getHour());
System.out.println(localDateTime.getMinute());
System.out.println(localDateTime.getSecond());
System.out.println(localDateTime.getNano());
//With time zone information
ZonedDateTime zoneDatetime = ZonedDateTime.now();
System.out.println(zoneDatetime.getYear());
System.out.println(zoneDatetime.getMonthValue());
System.out.println(zoneDatetime.getDayOfMonth());
System.out.println(zoneDatetime.getHour());
System.out.println(zoneDatetime.getMinute());
System.out.println(zoneDatetime.getSecond());
System.out.println(zoneDatetime.getNano());
System.out.println(zoneDatetime.getZone().getId()); // 「Asia/"Tokyo" is output
JapaneseDate japaneseDate = JapaneseDate.now();
System.out.println(japaneseDate.getEra()); //"Heisei" is output
System.out.println(japaneseDate.get(ChronoField.YEAR_OF_ERA)); //"29" is displayed
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime tomorrow = localDateTime.plusDays(1);
System.out.println(tomorrow.getDayOfMonth()); //"30" is output when executed on November 29th
LocalDateTime yesterday = localDateTime.minusDays(1);
System.out.println(yesterday.getDayOfMonth()); //"28" is output when executed on November 29th
--Use plus Years (long years)
if you want to add years
--If you want to subtract years, use minus Years (long years)
--For other addition / subtraction, LocalDateTime class
It is now supported as standard.
String coffee = "coffee milk";
Encoder encoder = Base64.getEncoder();
String encodeCoffee = encoder.encodeToString(coffee.getBytes());
System.out.println(encodeCoffee); //"44Kz44O844OS44O854mb5Lmz" is output
Decoder decoder = Base64.getDecoder();
String decodeCoffee = new String(decoder.decode(encodeCoffee));
System.out.println(decodeCoffee); //"Coffee milk" is output
By using String.join ()
, it is now possible to easily join multiple strings with any string.
String[] gyunyu = {"coffee milk", "Lemon milk", "Strawberry milk"};
System.out.println(String.join("###", gyunyu)); //"coffee milk###Lemon milk###Output with "strawberry milk"
List<String> gyunyu = new ArrayList<>();
gyunyu.add("coffee milk");
gyunyu.add("Lemon milk");
gyunyu.add("Strawberry milk");
System.out.println(String.join("###", gyunyu)); //"coffee milk###Lemon milk###Output with "strawberry milk"
Similar joins can be made with the java.util.StringJoiner
class.
StringJoiner gyunyu = new StringJoiner("###");
gyunyu.add("coffee milk");
gyunyu.add("Lemon milk");
gyunyu.add("Strawberry milk");
System.out.println(gyunyu); //"coffee milk###Lemon milk###Output with "strawberry milk"
The StringJoiner class can also be joined by specifying a prefix and suffix.
StringJoiner gyunyu = new StringJoiner(" > ", "[Like]", "[Hate]");
gyunyu.add("coffee milk");
gyunyu.add("Lemon milk");
gyunyu.add("Strawberry milk");
System.out.println(gyunyu); //「[Like]coffee milk>Lemon milk>Strawberry milk[Hate]Is output
It is written in the following grammar.
(Method arguments) -> {processing}
By using a lambda expression, it seems that the process can be written concisely ... When there is the following interface and processing
public interface Gyunyu {
public void output(String v);
}
Gyunyu gyunyu = new Gyunyu() {
@Override
public void output(String v) {
System.out.println(v);
}
};
gyunyu.output("coffee milk"); //「coffee milk」と出力される
Using a lambda expression, you can write something like the following.
Gyunyu gyunyu = (String v) -> { System.out.println(v); };
gyunyu.output("coffee milk"); //「coffee milk」と出力される
Furthermore, the argument type is inferred and can be omitted. If there is only one argument, the parentheses "()" can also be omitted. If there is only one expression, the curly braces "{}" can be omitted, so the description can be as follows.
Gyunyu gyunyu = v -> System.out.println(v);
gyunyu.output("coffee milk");
An interface that declares only one abstract method. If you make the Gyunyu interface written in the lambda expression a functional interface, The description is as follows.
Gyunyu.java
@FunctionalInterface
public interface Gyunyu {
public void output(String s);
}
By adding the @FunctionalInterface
annotation, it is possible to explicitly indicate that it is a functional interface.
It will be possible to issue a compile error if the conditions of the functional interface are not met.
Since method references can omit arguments, the amount of description can be reduced compared to lambda expressions. How to execute static method or instance method.
--Notation method
Class name (instance name) :: method name
Gyunyu gyunyu = System.out::println;
gyunyu.output("coffee milk"); //「coffee milk」と出力される
If you describe the above with a lambda expression, you can write it as follows.
Gyunyu gyunyu = v -> System.out.println(v);
gyunyu.output("coffee milk");
If the method you want to refer to is your own class, use this
Main.java
public void println(String v) {
System.out.println(v);
}
public void execute() {
List<String> gyunyu = Arrays.asList("coffee milk", "Strawberry milk", "Lemon milk");
gyunyu.forEach(this::println);
}
public static void main(String[] args) {
(new Main()).execute();
}
Main.java
public static void output(String v) {
System.out.println(v);
}
public static void main(String[] args) {
List<String> gyunyu = Arrays.asList("coffee milk", "Strawberry milk", "Lemon milk");
gyunyu.forEach(Main::output);
}
Stream API API that can aggregate values and process using data. The basic processing flow is
--For arrays
String[] gyunyu1 = {"coffee milk", "Coffee milk", "Strawberry milk", "Strawberry milk", "Lemon milk", "Lemon milk"};
Stream<String> stream1 = Arrays.stream(gyunyu1);
String[] gyunyu2 = {"Melon milk", "Apple milk", "Melon milk", "Grape milk"};
Stream<String> stream2 = Stream.of(gyunyu2);
--For Collection
List<String> gyunyu3 = Arrays.asList("fruits", "Banana", "Watermelon");
Stream<String> stream3 = gyunyu3.stream();
--For Map
Map<String, String> gyunyu4 = new HashMap<>();
gyunyu4.put("1", "Peach milk");
gyunyu4.put("2", "Loquat");
gyunyu4.put("3", "Fig milk");
Stream<Entry<String, String>> stream4 = gyunyu4.entrySet().stream();
Reference: Stream generation
Processing to narrow down and edit Steam and create a new Stream.
--When narrowing down the elements
--By using the filter
method, you can get the Stream of only the specified element.
//I want to extract only the character string containing milk
String[] gyunyu1 = {"coffee milk", "Coffee milk", "Strawberry milk", "Strawberry milk", "Lemon milk", "Lemon milk"};
Stream<String> stream1 = Arrays.stream(gyunyu1);
stream1.filter(s -> s.contains("milk"));
--If you want to remove duplicate elements
--You can get the Stream with duplicate elements removed by using the distinct
method.
//I want to remove duplicate milk
String[] gyunyu2 = {"Melon milk", "Apple milk", "Melon milk", "Grape milk"};
Stream<String> stream2 = Stream.of(gyunyu2);
stream2.distinct();
--If you want to convert elements
--You can get the Stream with updated elements by using the map
method.
//I want to add milk
List<String> gyunyu3 = Arrays.asList("fruits", "Banana", "Watermelon");
Stream<String> stream3 = gyunyu3.stream();
stream3.map(s -> s + "milk");
Reference: Intermediate operation
When the termination process is executed, the intermediate process is evaluated.
--If you want to get the number of elements
--You can get the number of elements by using the count
method.
//I want to output the number of cases including milk
Map<String, String> gyunyu4 = new HashMap<>();
gyunyu4.put("1", "Peach milk");
gyunyu4.put("2", "Loquat");
gyunyu4.put("3", "Fig milk");
Stream<Entry<String, String>> stream4 = gyunyu4.entrySet().stream();
System.out.println(stream4.filter(s -> s.getValue().contains("milk")).count()); //"2" is output
--When you want to take out elements one by one and operate them
--Side effects can be generated by using the forEach
method.
String[] gyunyu1 = {"coffee milk", "Coffee milk", "Strawberry milk", "Strawberry milk", "Lemon milk", "Lemon milk"};
Stream<String> stream1 = Arrays.stream(gyunyu1);
stream1.filter(s -> s.contains("milk")).forEach(s -> System.out.println(s));
Reference: Termination processing
Since the service I am in charge of in business runs on Java 5 and 6, I do not have the opportunity to use 8 in business, but I would like to create an opportunity to upgrade the version. I'm not familiar with StreamAPI and lambda expressions yet, so I feel I need to learn more about these two features.
Recommended Posts