This article is the 22nd day article of Fujitsu extended Advent Calendar 2016. Please note that the following content is not representative of the company / organization to which you belong, and is my own opinion.
You must obtain at least one qualification (eg, Applied Information Technology Engineer Examination) specified by joining the company as a new graduate, and the title Java SE 8 Programmer II Oracle certification that can be obtained by passing /pls/web_prod-plq-dad/db_pages.getpage?page_id=5001&get_params=p_exam_id:1Z0-809&p_org_id=70) Qualifications ** Oracle Certified Java Programmer, Gold SE 8 ** (hereafter referred to as Gold), and one rank lower [Java SE 8 Programmer I](http://education.oracle.com/pls/web_prod- They also include ** Oracle Certified Java Programmer, Silver SE 8 ** (hereafter referred to as Silver), which can be obtained by passing plq-dad / db_pages.getpage? Page_id = 5001 & get_params = p_exam_id: 1Z0-808 & p_org_id = 70). I will. An overview of Oracle-certified Java 8 qualifications is also posted at this URL, but also in the table below. I tried to summarize it in my own way.
name | Prerequisite qualifications | Qualification exam | target |
---|---|---|---|
Java Programmer, Bronze SE 7/8 | None | Java SE 7 / 8 Bronze | For beginners who can understand basic grammar such as if statements and object-oriented programming. |
Java Programmer, Silver SE 8 | None | Java SE 8 Programmer I | Classes like polymorphism and downcast(interface)Relationships andString 、ArrayList Class, lambda expression from Java8, date/For developers who understand the basic specifications of standard methods such as the basic usage of the time API. |
Java Programmer, Gold SE 8 | Java Programmer, Silver SE 8 | Java SE 8 Programmer II | Design of Immutable objects, generics, inner classes, etc., Java I/O(NIO.Including 2 systems), Executor framework, etc. For experts who can understand grammar and design in detail. |
Same as above | Java Programmer, Gold SE 7 | Upgrade to Java SE 8 Programmer | Same as above |
Same as above | Java Programmer(SE 6 or earlier) | Upgrade to Java SE 8 OCP ( Java SE 6 and all prior versions) | Same as above |
When I was a student, I had the experience of developing simple Android applications on my own using Java, and I often handle Java in my work, so I wanted to achieve the quota for acquiring qualifications early on as a newcomer. Therefore, I aimed to acquire Silver, which is a prerequisite qualification for Gold. As a result, I passed Silver relatively easily in early September of this year, which was not enough for self-improvement, so I want to study more advanced Java grammar knowledge & recently (Java8, Java9) Java interface design In order to grasp the trend, I decided to aim for Gold, which is more difficult than Silver.
Oracle official URL It is described with notes about. In this column, I will cite the bullet points of the topics that appear in it and explain them. I hope that those who take the Gold exam will be asked this way, and those who do not take the exam will feel that the latest Java official API is like this. In addition, Gold can not be acquired unless you acquire Silver, so of course we will proceed on the premise that you understand all the question range in Silver as described in the above table.
- Implement encapsulation
- Implement inheritance including access modifiers and compositions
- Implement polymorphism
- Override the
hashCode
, ʻequalsand
toString` methods of the object class- Create and use singleton and immutable classes
- Use the keyword
static
in initialization blocks, variables, methods and classes- Write code that uses abstract classes and methods
- Write code that uses the keyword
final
- Create inner classes such as static inner classes, local classes, nested classes, anonymous inner classes, etc.
- Use enums, including those whose methods and constructors are in enums.
- Write code that declares, implements, and extends interfaces. Use
@Override
annotations- Create and use lambda expressions
There is a lot of overlap with Silver, but it is better to understand that creating anonymous classes is strongly related to the functional interface and stream API that will appear later. Also, I remember having problems such as how to design an existing class into an Immutable class. Furthermore, in the enumeration type (ʻEnumclass), the constructor must be given a private modifier, but it is actually public, so the correct answer is to select "Compile error at line XX". There was also a problem that the correct answer would not be noticed unless you read the details such as. Java 8 allows you to define
default` and concrete static methods in your interface. So
interface A {
void foo();
}
interface B extends A {
@Override
default void foo() {}
}
interface C extends A {
@Override
default void foo() {}
}
class D implements B, C {}
You can inherit diamonds like this. Naturally, a compile error will occur on the line class D implements B, C {}
. Also,
interface E {
default void x(String s) {}
static void y(String s) {}
void z(String s);
}
An interface definition like ʻE e = s-> System.out.println (s); is because it is a functional interface (
default method and concrete
static` method are ignored). You can write lambda expressions. Even in the actual exam, I think there was one question based on this content.
By the way, the compilation specifications of local classes and anonymous classes have changed between Java 7 and Java 8.
class Outer {
private static String a = "A";
public static void main(String[] args) {
Outer q = new Outer();
q.foo("B");
}
public static void foo(String b) { //Implicitly assigns final modifier to variable b from Java 8
String c = "C"; //Implicitly assigns final modifier to variable c from Java 8
Inner inner = new Inner(){
@Override
public void bar(String d) {
System.out.println(a + b + c + d);
}
};
//b = "BB";
//c = "CC";
inner.bar("D");
}
interface Inner {
public void bar(String d);
}
}
When I compile with the version 1.7 compiler, I get a compile error saying that the local variables b
and c
must be declared as final
, but in version 1.8 the compilation passes. This is because Java 8 has become a specification that implicitly adds the final
modifier to the local variables b
and c
at compile time, and the background is the introduction of the lambda expression described later. I think it's because I wanted it to look natural as if I was passing an anonymous class as a function. However, since the local variables b
and c
are implicitly given the final
modifier, it is NG to uncomment theb = "BB"
andc = "CC"
. A compile error will occur regardless of whether the version of javac
is 1.7 or 1.8. By the way, when the above source code is compiled and executed, ʻABCD` is output.
- Create and use generics classes
- Create and use ʻArrayList
,
TreeSet,
TreeMapand ʻArrayDeque
objects- Use the
java.util.Comparator
andjava.lang.Comparable
interfaces
In Java, arrays are covariant, but I remember having problems with generics being immutable. In other words
Number[] array = new Integer[3];
Will compile, but
ArrayList<Number> list = new ArrayList<Integer>(3);
Will result in a compilation error. There was also one wild card and one boundary wild card. For example
ArrayList<?> list = new ArrayList<Integer>();
Will compile, but
ArrayList<Integer> list = new ArrayList<?>();
ArrayList<?> list = new ArrayList<?>();
Will result in a compilation error on both lines. This is because wildcards should not be used on the right side of =
. Also,
ArrayList<? extends Number> list = new ArrayList<Integer>();
Will compile, and for that matter
List<? super Integer> list = new ArrayList<Number>();
Will also compile.
You should fully understand the specifications of the java.lang.Comparable
and java.util.Comparator
interfaces. In that regard, the key class you add to the java.util.TreeMap
instance must have a java.lang.Comparable
interface ʻimplements, but if you don't ʻimplements
, it will be at runtime
. A lava.lang.ClassCastExceptionis thrown (note that this is not a compilation error). By the way, no questions related to
Deque` were given. Maybe it's just a whim.
- Use the built-in interfaces included in the
java.util.function
package, such asPredicate
,Consumer
,Function
,Supplier
- Use a functional interface that handles primitive types
- Use a functional interface with two arguments
- Write code that uses the'UnaryOperator'interface
Since it is a necessary description for the stream API described later, I think it was ** the field with the second largest number of questions **. Be sure to remember the following four interface names, which I personally name ** Four Tenno **, and their abstract method names. If you remember at least these four, interfaces with Bi
such asBiConsumer <T, U>
and primitive types (ʻint,
long,
double,
boolean) You don't have to remember the interfaces like
DoublePredicate and
LongToDoubleFunction`, which are specialized for.
Interface name | Abstract method name | Remarks |
---|---|---|
Function<T, R> |
R apply(T t) |
Four heavenly kingsOne of |
Consumer<T> |
void accept(T t) |
Four heavenly kingsOne of |
Supplier<T> |
T get() |
Four heavenly kingsOne of |
Predicate<T> |
boolean test(T t) |
Four heavenly kingsOnly one of them, this guy will be asked in Silver |
BiFunction<T, U, R> |
R apply(T t, U u) |
- |
UnaryOperator<T> |
T apply(T t) |
Function<T, T> Subinterface |
BinaryOperator<T> |
T apply(T t1, T t2) |
BiFunction<T, T, T> Subinterface |
IntFunction<R> |
R apply(int value) |
- |
ToDoubleFunction<T> |
double applyAsDouble(T t) |
double apply(T t) is not |
IntToDoubleFunction |
double applyAsDouble(int value) |
double apply(T t) is not |
IntConsumer<T> |
void accept(int value) |
- |
IntSupplier<T> |
int getAsInt() |
int get() is not |
IntPredicate<T> |
boolean test(int value) |
- |
java.util.function
package is [Official API Collection](https://docs.oracle.com/javase/jp/8/docs/api /java/util/function/package-summary.html).More important than this knowledge, it is natural that you can associate a functional interface with a lambda expression (or see the method described later), but conversely, you can associate a functional interface with which functional interface you used. Is to be. For example, in the case of the Supplier <String>
interface, you can return the String
type from the void
type, so
Supplier<String> a = () -> "HelloWorld!"
Being able to define lambda expressions like
b = s -> s.concat("World!")
You just have to look at the lambda expression in and associate the variable type of the variable b
withFunction <String, String>
or UnaryOperator <String>
. And it's also important to be able to associate how abstract methods should be used to actually apply a functional interface. If you wanted to use a lambda expression in the previous example to assign a string of HelloWorld!
To a variable of type String`` str
, then String str = a.get ();
or String str = b. Just write apply ("Hello");
.
Further applied the above knowledge
DoubleFunction<BiConsumer<Integer, Double>> func = x -> (y, z) -> System.out.println(x / z + y);
There was also a nested lambda expression like. If you want to output the calculation result of 5.0 / 2.0 + 3 = 5.5
, writefunc.apply (5.0) .accept (3, 2.0);
.
- Describe stream interfaces and pipelines
- Filter collections using lambda expressions
- Use method references with streams
- Extract data from an object using the
peek ()
andmap ()
methods, including the base version of themap ()
method- Search for data using search methods such as
findFirst
,findAny
, ʻanyMatch, ʻallMatch
,noneMatch
- ʻUse the Optional` class
- Write code that uses the stream's data and compute methods
- Sort collections using stream API
- Use the
collect ()
method to save the results in a collection. Group / partition data using theCollectors
class- Use the
flatMap ()
method
Partly because it is the main feature of Java8, ** the number of questions is very large, and I think that about 50% of the problems were actually related to the stream API **. I think all the columns I wrote in the bullet points above are important.
Streams use the Stream <T>
interface and the ʻIntStream` interface specialized for its primitive type, and operate according to the following flow.
However, please note the following points. This content should also be remembered in connection with the actual exam.
The biggest advantage of the stream API is that you can code 1 to 3 actions in one line **, which is expected to improve the readability of the code and find bugs immediately. For example, suppose you want to write Java code that outputs all sibling and child files / directories from the current directory using NIO.2 added from Java 7 described later. At this time, in javac version 1.7, it was necessary to code a long number of lines by overriding the four abstract methods of the FileVisitor
interface as shown below.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
class Search7 {
public static void main(String[] srgs) {
try {
Files.walkFileTree(
Paths.get("./"),
new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
System.out.println(dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
On the other hand, in version 1.8, you only need ** very short number of lines ** as below.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
class Search8 {
public static void main(String[] srgs) {
try {
Files.walk(Paths.get("./")).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Note that System.out :: println
in the Java 8 code is a notation added from Java 8 and is called a method reference. This notation has the same meaning as the lambda expression (Path path)-> System.out.println (path)
and can be written even shorter than the lambda expression. Please note that in the actual test, there were quite a few questions related to the functional interface. For example
ToDoubleFunction<String> ds = str -> Double.parseDouble(str);
Can be rewritten as follows.
ToDoublefunction<String> = Double::parseDouble;
From the description of the lambda expression, it is good if you can imagine how to describe the method reference and vice versa. Now, let's return to the explanation of the stream API, but as a test preparation, I will explain according to 1 to 3 above. First, take a look at the code using the stream API below.
Stream<String> stream1 = Arrays.asList("a", "bb", "ccc", "dddd").stream(); //Stream generation
Stream<Integer> stream2 = stream1.map(str -> str.length()); //Intermediate operation part 1
Stream<Integer> stream3 = stream2.filter(num -> num > 1); //Intermediate operation part 2
Optional<Integer> result = stream3.max((num1, num2) -> num1 - num2); //Termination operation
result.ifPresent(max -> System.out.println(max));
The stream generation function on the first line is an instance of the stream with the type parameter T``stream1
by stream ()
newly added as a default
method in the Collection <T>
interface in Java 8. Is being generated. Since the ʻArrays.asList ()method returns the
List interface, which is a subinterface of the
Collection interface, there were a lot of questions about creating streams using this method. The intermediate operation
map () on the second line is a lambda expression to call
length () of the
Stringclass for each of the four elements of type
String held in
stream1. It is specified. As a result, the four elements of type
String are converted to type ʻInteger
, which is a wrapper class of type ʻint, which is the return value of
length () . Therefore, the values held by
stream2 generated by
map () are
1, 2, 3, 4. Note that primitive types such as ʻint
cannot be described in generics (a compilation error will occur).
Also, in the second intermediate operation filter ()
on the third line, the values 1, 2, 3, 4
held by stream2
are filtered to reduce the number of values held. doing. The filtering specification also uses a lambda expression, which in this example specifies that only elements with a value greater than 1 are retained and the rest are discarded. Therefore, the values held by stream3
are 2, 3, 4
.
Finally, the termination operation max ()
, which returns the maximum of the values 2
, 3
, and 4
held by stream3
. However, when finding the maximum value, the definition of maximum must be specified in the argument of max ()
. This argument is of type java.util.Comparator <T>
, and the lambda expression (num1, num2)-> num1 --num2
that represents its abstract method ʻint compare (T num1, T num2)It is specified. By this specification, the maximum value in natural order is calculated, so the flow is to return
4. Note that an operation in which it has been confirmed that all the elements
2,
3, and
4are used by the termination operation in this way is called a reduction operation. However, looking at the above example,
max () returns an instance
result of type ʻOptional <T>
. The ʻOptional class is a container class that stores the result of the stream termination operation, and even if the termination operation result is
null, the ʻOptional <T>
instance can store null
. At that time, the biggest feature is that the ʻOptional instance itself does not become
null. In the above example, the last line calls ʻifPresent (Consumer <? Super T> consumer)
of the ʻOptional class, and if a value other than
nullis stored, it is specified by an argument. If the lambda expression of
consumer is executed and
nullis stored, nothing is done. From this, I think you can read the design that ** eliminates the risk of throwing
java.lang.NullPointerExceptionat runtime **. From the above, since
4 is stored in
result,
4 is in
maxof the lambda expression
max-> System.out.println (max)of type
Consumer . It will be applied as is and will be output as
4`.
If you write the above example in one statement and apply all the method references, the description will be as follows (of course, the execution result is the same).
Optional<Integer> result =
Arrays.asList("a", "bb", "ccc", "dddd").stream() //Stream generation
.map(String::length) //Intermediate operation part 1
.filter(num -> num > 1) //Intermediate operation part 2
.max((num1, num2) -> num1 - num2); //Termination operation
result.ifPresent(System.out::println);
In addition to the above, there are many methods for creating streams, performing intermediate operations, and performing terminating operations. I will omit it because it is troublesome to write articles any more ~~, but if you want to be strong in stream API [Official API collection](https://docs.oracle.com/javase/jp/8/docs/api /java/util/stream/Stream.html) Please refer to it. In the actual exam, I feel that all 10 of the 10 bullet points written at the top were given.
- Use try-catch and
throw
statements- Use
catch
, multi-catch andfinally
clauses Use Autoclose resources with + try-with-resources statement- Create custom exceptions and auto-closeable resources
- Test invariants using assertions
Try-with-resource is a convenient function added from Java 7, but even in the SE8 Gold exam, there were quite a few questions in connection with JDBC, which will be described later. At this time, you need to be careful when the overridden close ()
method and catch
clause are executed.
class Main {
static class X implements AutoCloseable {
X() {
System.out.println("X : Constructor");
}
@Override
public void close() {
System.out.println("X : close()");
}
}
static class Y implements AutoCloseable {
Y() {
System.out.println("Y : Constructor");
}
@Override
public void close() {
System.out.println("Y : close()");
}
}
public static void main(String[] args) {
try (X x = new X();
Y y = new Y()) {
throw new Exception("Exception");
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
System.out.println("finally");
}
}
}
When you compile the above source file and execute it
X : Constructor
Y : Constructor
Y : close()
X : close()
Exception
finally
Is output. Even though the variable y
is defined after the variable x
, it is easy to get caught without knowing the try-with-resource specification that the close ()
method calls them in reverse order. Also, it is easy to misunderstand that ʻException is output before
Y: close () because it is dragged by the execution order of
tryclause →
catch clause →
finallyclause so far. .. If you remember each of the above results, you can prevent getting caught or misunderstood. In addition, when overriding a method defined as
throws Exception or
throws RuntimeExceptionin a superclass, there is one question about how to specify
throws for a method in a subclass. did. Surprisingly, there were two assertion-related questions. Since you only need to learn the syntax of the ʻassert
keyword, this is an area that you want to use as a score source.
- Date-based and time-based events, such as using
LocalDate
,LocalTime
,LocalDateTime
, ʻInstant,
Period, and
Duration` to combine dates and times into a single object. Create and manage- Manipulate dates and times across multiple time zones. Manage daylight savings time changes, such as formatting date and time values
- Use ʻInstant
,
Period,
Durationand
TemporalUnit` to define, create and manage date-based and time-based events.
It's a different API from the stream API newly implemented in Java8, but I think it wasn't asked much. I don't think I've seen any issues with ZonedDateTime
, ʻInstantclasses, date / time formats, daylight savings time, including zone information ... However, as was the case with Silver, the hooking problem using the fact that the LocalXXX class is an Immutable class was also asked in Gold. Besides,
Period is the date,
Durationis the time interval, and I feel that it is enough to remember the ISO 8601 notation of the time, so if the only purpose is to acquire Gold, knowledge of Silver + α I think the degree is enough. In addition, the
Date class and
Calendarclass in the old
java.utilpackage did not have any questions. Will it eventually become
@deprecated` as the date / time API of the one added to SE 8 becomes mainstream?
Java I/O、NIO.2
- Read / write data to the console
- Use
BufferedReader
,BufferedWriter
,File
,FileReader
,FileWriter
,FileInputStream
,FileOutputStream
, ʻObjectOutputStream, ʻObjectInputStream
andPrintWriter
in thejava.io
package To do- Manipulate file and directory paths using the
Path
interface- Use stream API with NIO.2.
Despite the fact that there are many problems that cannot be solved without knowing the method specifications, the number of questions in the exam is unexpectedly reasonable. It was the field that I was not good at at that time, so I actually moved my hand while looking at the Official API Collection. It's best to understand while implementing the test sample. I think that NIO.2 had more questions than I / O streams that existed for a long time than NIO.2 added in Java 7 (note that it is completely different from the stream API added in Java 8). I will.
First of all, the former input / output stream, when a BufferedReader
instance is created for a given file,read ()
,readLine ()
,mark () from the character string written in the file. There was actually a problem with how it was output using
,reset ()
andskip ()
. Here's a quick summary of the differences between read ()
and readLine ()
in the table below.
Method name | Reading unit | Return type | At the end of the file |
---|---|---|---|
read() |
One character | int (Normal,char Explicitly cast to type to one character) |
-1 return it |
readLine() |
1 line | String (The line feed code is automatically detected and is not included in the return value.) |
null return it |
Here, BufferedReader
declares the Reader
interface ʻimplements and declares
mark () ,
reset () , etc. in that interface, but all implementation classes of
Readersupport operations. Not always. Running these with an unsupported
Reader implementation class will throw a
java.io.IOException at run time. This support status can be determined by the return value (
boolean type) of
markSupported () . I don't remember the question status of I / O streams other than
BufferReader, but I think that at least the
java.io.Serializable interface and ʻObjectOutputStream
were not asked. Also, for console I / O relations, you can use the System.in
variable of the ʻInputStream type and the
System.out variable of the ʻOutputStream
type, but thejava.io.Console added from Java 6 You can also use the
class. I think the points of this class are the following two.
Console
instance cannot be initialized using new
, it is initialized by substituting the return value of System.console ()
readline ()
, which reads one line from the console, returns a String
type, while readPassword ()
, which hides it on the console and reads one line, returns achar []
type.I think the remaining NIO.2 is rather important. NIO.2 is stored in the package following java.nio
, and implements a function that can manipulate file / directory information that cannot be realized by input / output streams. In the actual test, only the static
methods that operate them are provided.copy (Path from, Path to, CopyOption ... option)
,move (Path from, Path to, CopyOption) of the
Filesclass. ... option)
is given one by one, and you need to pay attention to the execution results such as LinkOption.NOFOLLOW_LINKS
and StandardCopyOption.REPLACE_EXISTING
, which allow you to specify options as variable length arguments after the third argument. .. In addition, there are readAllLines (Path path)
and lines (Path path)
as methods that can read all the sentences in the file line by line. The table below briefly summarizes the differences between them.
Method name | Return type | Introduced version |
---|---|---|
static readAllLines(Path path) throws IOException |
List<String> |
Java7 |
static lines(Path path) throws IOException |
Stream<String> |
Java8 |
By the way, the Path
interface is specified as an argument of the methods of these Files
classes. There were a couple of questions about this Path
interface alone. Of course, there is no constructor in the Path
interface, and you can create an instance from the following two ways.
get (String first, String ... more)
method of the factory class Paths
class (just remember this)getPath (String first, String ... more)
method in the implementation class of the FileSystem
interfaceNote that the absolute / relative path specified in the Path
interface argument does not represent the 0th root directory, but the directory / file closest to the root directory. For example
Path path = Paths.get("/usr/bin/java");
System.out.println(path.getName(0));
System.out.println(path.subpath(1, 3));
Will produce the following output.
usr
bin/java
In addition, you should be careful about the difference in behavior when resolve ()
and normalize ()
are executed for the Path
object with relative path and absolute path.
- Create a worker thread using
Runnable
andCallable
. ʻRun tasks concurrently using ExecutorService`- Identify potential threading issues such as deadlocks, starvations, live rocks and race conditions
- Use the keywords
synchronized
and thejava.util.concurrent.atomic
package to control the thread execution order- Use collections and classes of
java.util.concurrent
such asCyclicBarrier
andCopyOnWriteArrayList
- Use parallel Fork / Join framework
- Use parallel streams for reduction, decomposition, merge process, pipeline, performance, etc.
First, let's learn the basic usage of parallel processing using threads using the Thread
class and Runnable
interface, and the basic usage of exclusive processing and synchronous processing. For exclusive processing, specify the synchronized
modifier to the method or block, and for synchronous processing, use java.util.concurrent.CyclicBarrier
. Note that the Runnable
interface is a functional interface with one abstract method,run ()
, so you can assign lambda expressions.
I think that the Executator framework had about two questions, but I think that you can not understand the movement unless you know it. The Execurator framework introduces the concept of a thread pool that spawns multiple threads at once when instantiating and stores them until they are used. In addition, it implements the execution scheduling function of each thread and demonstrates excellent thread reusability performance. To prepare for the exam, you need to understand the behavior of ʻExecutor Service. See the code below for an example of using ʻExecutorService
.
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Runnable : " + i);
}
}
};
Callable<Integer> c = new Callable<Integer>() {
@Override
public Integer call() {
int i = 0;
for (; i < 5; i++) {
System.out.println("Callable : " + i);
}
return i;
}
};
ExecutorService es = null;
try {
es = Executors.newFixedThreadPool(3);
es.execute(r);
Future<?> f1 = es.submit(r);
Future<Integer> f2 = es.submit(c);
System.out.println(f1.get() + " : " + f2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
es.shutdown();
}
ʻExecutors.newFixedThreadPool (3) creates a ʻExecutorService
instance ʻesthat represents a thread pool with a fixed number of 3 threads. Run the predefined
Runnable tasks on this instance with ʻexecute ()
using one of three threads. Tasks can also use the Callable <T>
interface instead of the Runnable
interface, the differences being shown in the table below.
Functional interface name | Abstract method | Return type | checked Exception throwability |
---|---|---|---|
java.lang.Runnable |
run() |
you have tovoid To |
impossible |
java.util.concurrent.Callable |
call() |
Type parametersT Specified by |
throws Possible by specification |
At this time, the thread execution function has one of the following four patterns.
Method name | Return type | After executing the taskFuture Value stored in |
---|---|---|
execute(Runnable task) |
void |
- |
submit(Runnable task) |
Future<?> |
null |
submit(Runnable task, T t) |
Future<T> |
t |
submit(Callable<T> task) |
Future<T> |
Callable<T> ofT call() Value returned by |
Future <T>
is an interface that represents the task execution result, and you should remember the mechanism that the thread waits until the task is completed by get ()
and returns the result of T
type as it is when it is completed. is. From the above, in the line System.out.println (f1.get () +": "+ f2.get ());
null : 5
Is output. Finally, run shutdown ()
to shut down ʻesand stop accepting new tasks. If you don't call the
shutdown ()method, the program will not end and will continue to wait after all threads have finished processing. I think that the image will come out just by remembering the series of operations as described above. In addition to the
CyclicBarrier, the
java.util.concurrentpackage implements thread-safe
List,
Map,
Set, and
Queue` interfaces. For example, see the code below.
List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
new Thread(){
@Override
public void run() {
for (Integer num : list) {
System.out.println("Thread : " + num);
}
}
}.start();
for (Integer num : list) {
System.out.println("Remove : " + num);
list.remove(num);
}
At first glance, the result seems to change with each execution, but in reality, the exception java.util.ConcurrentModificationException
is always thrown.
Exception in thread "Thread-0" Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Main.main(Main.java:18)
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Main$1.run(Main.java:12)
The Java extension for
statement calls the iterator (= ʻIterator interface) implemented in the collection, but adds elements of the collection that are not thread-safe, such as ʻArrayList
, during iteration by that iterator. / This is because the specification throws an exception java.util.ConcurrentModificationException
when deleted. I personally think that this is one of the pains that you can't understand until you actually implement it. As a workaround
List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
Replace the line with the thread-safe java.util.concurrent.CopyOnWriteArrayList
class as shown below.
List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(0, 1, 2, 3, 4));
There are many thread-safe collections besides CopyOnWriteArrayList
, but for now summary of classes provided in the java.util.concurrent
package You just need to take a quick look at (/jp/8/docs/api/java/util/concurrent/package-summary.html) to determine which collections are thread-safe.
I remember that one question was given from each of the atomic and Fork / Join frameworks. Atomic (= a series of indivisible operations) was given the ʻAtomicInteger class, which defines a method that performs exclusive processing such as the
synchronized modifier on primitive types such as ʻint
. The Fork / Join framework only needs a rough understanding of how to write the overall code.
- Describes the interfaces that make up the core of the JDBC API, including the
Driver
,Connection
,Statement
, andResultSet
interfaces and their relationship to the provider's implementation.- Identify the components needed to connect to the database using the
DriverManager
class, such as JDBC URLs- Issue queries and read results from the database, including creating statements, retrieving result sets, repeating results, and closing result sets / statements / connections properly
JDBC mainly requires understanding of the following two perspectives.
In the actual exam, I remember that only about 4 questions about how to use the latter JDBC API were asked, but the knowledge of the former may also be asked as a multi-choice question, so it is necessary to understand the operation of the system. think. From now on, only the latter will be explained in this article. It is most important to understand how to use the JDBC API from the basic flow of coding that can connect / operate the database in the following order.
Connection
interface generated byDriverManager.getConnection ()
Statement
interface generated byConnection.createStatement ()
in 1.ResultSet
interface generated byStatement.executeQuery ()
in 2.All three of these objects can be tried-with-resource applied and close ()
executed. So be aware that executing any method on each closed object will throw a SQLException
. For example, for a variable ʻURLthat represents a URL that can connect to a given
private static final
String` type JDBC.
try (Connection cn = DriverManager.getConnection(URL);
Statement st = cn.createStatement()) {
ResultSet rs1 = st.executeQuery("SELECT id FROM shop");
ResultSet rs2 = st.executeQuery("SELECT name FROM shop");
if (rs1.next()) {
System.out.println(rs1.getInt(1));
}
if (rs2.next()) {
System.out.println(rs2.getString(1));
}
} catch (SQLException e) {
e.pribntStackTrace();
}
If you reuse the Statement
type variable st
as in, rs1
will be closed at the point where rs2
is generated. So rs1.next ()
throws a SQLException
.
Note that ResultSet
cares about the row / column index starting at 1 instead of 0. Therefore, for a variable rs
of type ResultSet
, rs.getString (0)
etc. will compile, but SQLException
will be thrown at runtime. However, rs.absolute (0)
does not throw a SQLException
at runtime even for compile errors. This is because running rs.absolute (0)
will move you to the blank line before the first line of rs
(by the way, this method returns a boolean
type and the result is a successful move. Returns true
as).
In addition to this, the following questions were asked, and both were asked one by one.
Statement.execeteQuery ()
ResultSet
interface
- Explain the benefits of localizing your application
- Use the
Locale
object to read and set the localeproperties
Create and read files- Create a resource bundle for each locale and load the resource bundle in your application
There are two ways to initialize a Locale
instance that represents a particular region:
Locale
class (country, language, and variant can be specified as arguments)static
variable of type Locale
such as Locale.US
or Locale.ENGLISH
Despite the fact that many Java standard APIs do not use new
these days, the Locale
class newly added in Java 8 has an unusual design that can be initialized using a constructor. The above Locale
variable initialization method was actually asked. It can also be initialized by the Locale.Builder
class, which is a static
nested class of the Locale
class, but I think that there was no initialization using it in the mock questions and actual tests described later. ..
Although not newly added in Java8, the ResourceBundle
abstract class that represents a resource bundle that centrally manages information such as language, numerical value, and passage information for each specific region is [Standard API](https: //). It exists at docs.oracle.com/javase/jp/8/docs/api/java/util/ResourceBundle.html). In the Java standard API, the following two methods have existed for a long time as a way to describe the above information to realize the resource bundle.
ListResourceBundle
abstract class, which is a subclass of ResourceBundle
, to your own class, override the abstract method public Object [] [] getcontents ()
, and add information to the definition in that method. How to writeproperties
In the actual test, I remember that only the latter of the above two design methods was asked, but I was also asked how to use the resource bundle using it. In this article, I would like to give both as examples. First, for the former, write a class that represents the following resources.
Test_ja_JP.java
package com.gold.eight.java;
import java.util.ListResourceBundle;
public class Test_ja_JP extends ListResourceBundle {
@Override
protected Object[][] getContents() {
String[][] contents = {
{"capital", "Tokyo"},
{"currency", "yen"},
{"language", "Japanese"}
};
return contents;
}
}
Recall that the reason why the return value is ʻObject [] []but returns
String [] []is because Java arrays are covariant as described in Generics. The 0th element is the key value and the 1st element is the key value, such as
java.util.Map <String, String>for the
String []nested inside the
String [] []. Enter the value that corresponds to the key value. Here, the class name is
Test_ja_JP, but
Test` is called the base name, followed by the underscore to describe the language code and country code of the locale information.
Now, let's use this resource as a resource bundle as follows.
Main.java
package com.gold.eight.java;
import java.util.Locale;
import java.util.ResourceBundle;
public class Main {
public static void main(String[] args) {
ResourceBundle rb = ResourceBundle.getBundle("com.gold.eight.java.Test", Locale.JAPAN);
System.out.println(rb.getString("capital"));
System.out.println(rb.getString("currency"));
System.out.println(rb.getString("language"));
}
}
When you compile and execute the above two java files, the output will be as follows.
Tokyo
yen
Japanese
Load the resource with the line ResourceBundle rb = ResourceBundle.getBundle ("com.gold.eight.java.Test", Locale.JAPAN);
. At this time, you must write "package name.base name" as a character string in the first argument of getBundle ()
. Also, since the Locale
instance can be specified as the second argument, Locale.JAPAN
corresponding to the language code and country code mentioned earlier is written. When reading the information written in the resource, getString ()
of the Resourcebundle
instance is used to specify the key value string as an argument, but if a nonexistent key value is specified, java.util. MissingResourceException
is thrown.
Also, the latter method of creating a properties
file can be described in the following format instead of Test_ja_JP.java
.
Test_ja_JP.properties
capital=Tokyo
currency=yen
language=Japanese
Here, too, the file name is the base name followed by an underscore, and the language code and country code of the locale information are described. If you want to use it as a resource bundle, it is the same as Main.java
.
I will write as much as I can remember how I spent from the time I started studying until I got Gold.
2016/9/10〜
Although I acquired Silver, I felt that I was not satisfied with my self-improvement, so I decided to acquire Gold the next day.
2016/9/17〜
I received the Oracle Certification Textbook Java Programmer Gold SE 8 (commonly known as purple book) that I found on Amazon, so study. have started. It's more like a textbook than a collection of problems, so I read it at a pace of three or four days a week, albeit irregularly. I think I started reading the second lap from mid to late October 2016. Underline the classes and methods that you see for the first time, and sometimes implement them by yourself while actually looking at the Official API Collection. I was deepening my understanding.
2016/10/23〜 While reading the second lap of the purple book, it is a Gold version of the problem collection that was taken care of at the time of Silver [Thorough capture Java SE 8 Gold problem collection [1Z0-809] correspondence](https: // www I learned about the release of .amazon.co.jp/dp/4295000035/ref=cm_sw_r_tw_dp_x_WjptybSP18FB5) (commonly known as Kuromoto), and immediately found it on Amazon. Silver's black book has a polite explanation, and questions that look exactly like the mock questions at the end of the chapter were given in the actual exam. So, I decided to solve it after reading and understanding the purple book two laps. I think the first page was actually opened from early to mid-November.
2016/11/23 I read purple books for more than two laps and read about half of black books, so I decided to apply for the exam. My goal was to get Gold in November, but there was no test center nearby that I could take the exam in November, so I had to apply for it on December 3rd.
2016/12/3 test day. When I actually received it, I felt it was easier than I had expected for purple and black books. I think that I finished solving everything including the review and sent the answer with the timing of about 1 hour remaining. Shortly thereafter, CertView sent me the results and I knew it passed.
Finally, I will write about until passing & what I noticed after passing.
After all, the first thing I noticed is that as the latest official API design comes, I somehow understand the flow of design history, such as throwing an exception at runtime instead of throwing an exception as much as possible **. For example, the concept of resource bundles came out before the time when generics came out (Java 5), so the return type of getContents ()
, which is an abstract method of ListResourceBundle
, is ʻObject [] []. It has become `. So
@Override
protected Object[][] getContents() {
Object[][] contents = {
{"A", "1"},
{"B", 2},
{"C", 3.0}
};
return contents;
}
You can compile scary code like this, as if you were asking me to raise a java.lang.ClassCastException
. From the introduction of the generics added after that, I somehow understand the design flow to reduce the risk of throwing java.lang.ClassCastException
by deciding where the type can be statically determined at compile time ( Well, you can cast using ʻinstance of ...). More recently, Java 8 has also added the ʻOptimal <T>
type, which attempts to reduce the infamous java.lang.NullPointerException
as much as possible. As a result, early bug detection can be expected in the development process, and the risk of the operating system going down is reduced.
Also, ** constructors such as Console
class and LocalDateTime
class can be hidden by specifying private
**, Path
interface, ʻExecuratorServiceinterface, etc. ** Abstract classes and interfaces use
new. Recently, there are an increasing number of designs that do not use constructors as much as possible by taking advantage of the fact that instances cannot be used. This is because it prevents the designer from using classes and methods that have been redefined by ʻextends
/ ʻimplements` that were not intended. It would be a problem for API designers and API users if an exception due to an incorrect order of method execution is always thrown by executing a method with an incorrect definition change.
Even so, most vendor qualifications are expensive for newcomers. I applied a discount ticket when I took the Gold exam, but if I pay the exam fee properly, it costs 26,600 yen for Silver and 26,600 yen for Gold, for a total of 53,200 yen. Well, it seems that there are qualifications for exam fees that are much higher than this. .. By the way, it seems that Java 9 will be released in March 2017, but will Java 9's Bronze, Silver, and Gold qualifications appear as well as Java 8? If so, I think that you can get Java 9 Gold by passing Upgrade to Java SE 9 Programmer, but if you pay the examination fee of 26,600 yen one by one, you will also need to pay the operating cost. Still, I would like to keep up with the latest trends in Java to the extent that I am not a qualification enthusiast. That said, if you had the Upgrade to Java SE 9 Programmer, would it be the most problematic issue with Project Jigsaw, which is the main feature of Java 9? ~~ jshell, I don't think I can make a problem in the first place. ~~
It was a poor article, but thank you for reading to the end.
Recommended Posts