dan1st | Daniel
dan1st | Daniel
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/24/2024 in #❓︱qotw-answers
Week 101 — How can a directory be deleted from Java code including subdirectories and files?
Files and directories can be deleted using the Files.delete method, e.g. using Files.delete(Path.of("/path/to/file"));. However, this only works for files and empty directories. To delete directories with contents, one first needs to delete all contents of that directory. Since a directory might have non-empty subdirectories, these need to be deleted recursively. To do that, one can use Files.list() to get a list of all files in the directory to delete and then call the method recursively for all found directories. After processing the content of a directory, it can be deleted:
public static void deleteDirectory(Path toDelete) throws IOException {
List<Path> entriesToDelete;
try(Stream<Path> entries = Files.list(toDelete)) {
for(Path entry : entriesToDelete.toList()) {
if(Files.isDirectory(entry)){
deleteDirectory(entry);
} else {
Files.delete(entry);
}
}
Files.delete(toDelete);
}
}
public static void deleteDirectory(Path toDelete) throws IOException {
List<Path> entriesToDelete;
try(Stream<Path> entries = Files.list(toDelete)) {
for(Path entry : entriesToDelete.toList()) {
if(Files.isDirectory(entry)){
deleteDirectory(entry);
} else {
Files.delete(entry);
}
}
Files.delete(toDelete);
}
}
Alternatively, it is possible to use Files.walk which recursively traverses the directory. Since that method finds the parent directories first, it is necessary to reverse the elements before iterating which can be done using the List#reversed method that has been added in JDK 21.
public static void deleteDirectory(Path toDelete) throws IOException {
try(Stream<Path> entries = Files.walk(toDelete)){
for(Path entry : entries.toList().reversed()) {
Files.delete(entry);
}
}
}
public static void deleteDirectory(Path toDelete) throws IOException {
try(Stream<Path> entries = Files.walk(toDelete)){
for(Path entry : entries.toList().reversed()) {
Files.delete(entry);
}
}
}
2 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
This keyword, along with Java's entire built-in serialization mechanism, is far less important today than when it was introduced to the language in JDK 1.1. The awkward semantics were the result of the limited language mechanisms that were available in the language at the time. Nowadays, there are much better tools for accomplishing the same thing. That said, the ecosystem does tend to respect the transient keyword or even adopt it for its own purposes. For instance, JPA will recognize transient fields in persistent classes and omit them from the persisted data. Lombok will ignore transient fields in its generated equals() & hashCode() implementations. Make sure to check the documentation of the frameworks and libraries you are using to see how transient fields are handled.
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
On the other side of the process, when objects of that class are deserialized (e.g. read with ObjectInputStream#readObject()), the transient fields will not be populated. The developer must account for these uninitialized fields by either setting them in the special readObject() method of the class, or by otherwise working around the empty value.
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
The transient keyword marks fields of a class as being excluded from the serialized state of an object. When a class is marked as serializable (implements the Serializable interface), the JVM will write the object's state during a serialization operation, such as with the ObjectOutputStream#writeObject​(Object obj) method. Fields marked as transient will be excluded from that mechanism.
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
Some third-party serialization libraries (like gson) also consider this keyword on fields and ignore transient fields during (de)serialization.
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
The transient keyword can be used to exclude some fields from serialization. For example, if someInt is marked transient, it will not be included in the serialized form and will be 0 when deserialized.
public class SomeDataClass implements Serializable {
private String someString;
private transient int someInt;
public SomeDataClass(String someString, int someInt){
this.someString = Objects.requireNonNull(someString);
this.someInt = someInt;
}
@Override
public String toString(){
return "SomeDataClass(someString=" + someString + ", someInt=" + someInt + ")";
}
}
public class SomeDataClass implements Serializable {
private String someString;
private transient int someInt;
public SomeDataClass(String someString, int someInt){
this.someString = Objects.requireNonNull(someString);
this.someInt = someInt;
}
@Override
public String toString(){
return "SomeDataClass(someString=" + someString + ", someInt=" + someInt + ")";
}
}
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/17/2024 in #❓︱qotw-answers
Week 100 — What's the purpose of the `transient` keyword?
Serialization can be used to convert an object to a different format that can be stored or transferred and then be deserialized to a different format. For example, binary serialization (using ObjectOutputStream/ObjectInputStream) can do that automatically for classes implementing Serializable:
public class SomeDataClass implements Serializable {
private String someString;
private int someInt;
public SomeDataClass(String someString, int someInt){
this.someString = Objects.requireNonNull(someString);
this.someInt = someInt;
}
@Override
public String toString(){
return "SomeDataClass(someString=" + someString + ", someInt=" + someInt + ")";
}
}
public class SomeDataClass implements Serializable {
private String someString;
private int someInt;
public SomeDataClass(String someString, int someInt){
this.someString = Objects.requireNonNull(someString);
this.someInt = someInt;
}
@Override
public String toString(){
return "SomeDataClass(someString=" + someString + ", someInt=" + someInt + ")";
}
}
//write an object of that class to a file
SomeDataClass obj = new SomeDataClass("Hello World", 1337);
try(ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Path.of("object.dat")))) {
oos.writeObject(obj);//write the object to the ObjectOutputStream which serializes it and passes it to the underlying OutputStream
}
//write an object of that class to a file
SomeDataClass obj = new SomeDataClass("Hello World", 1337);
try(ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Path.of("object.dat")))) {
oos.writeObject(obj);//write the object to the ObjectOutputStream which serializes it and passes it to the underlying OutputStream
}
//read an object from that file
SomeDataClass obj;
try(ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Path.of("object.dat")))){
obj = (SomeDataClass)ois.readObject();//WARNING: Deserialization (of untrusted data) is dangerous
}
//read an object from that file
SomeDataClass obj;
try(ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Path.of("object.dat")))){
obj = (SomeDataClass)ois.readObject();//WARNING: Deserialization (of untrusted data) is dangerous
}
It should be noted that (de)serialization can lead to many issues including compatibility, construction of invalid objects (e.g. deserialized data is typically not validated on construction) and deserialization of untrusted data can lead to security vulnerabilities (from denial of service to remote code execution, see also the Javadoc of Serializable). Because of these issues, binary (de)serialization using ObjectInputStream/ObjectOutputStream should be avoided in most cases.
7 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/10/2024 in #❓︱qotw-answers
Week 99 — What is the `ReentrantReadWriteLock` class used for and how can it be used?
A ReadWriteLock consists of two locks: One for reading and one for writing. The goal of it is that multiple threads can hold the read-lock concurrently but only one can hold the write-lock and only while no thread is holding the read-lock. If a a thread owns the read lock, the write lock cannot be obtained by any other thread and vice-versa. ReentrantReadWriteLock is an implementation of the ReadWriteLock interface that allows threads to obtain the lock even if they already have it.
private final ReadWriteLock LOCK = new ReentrantReadWriteLock();

//This method can run concurrently as often as needed but not concurrently with doWrite() (one has to wait for the other to finish)
public void doRead(){
Lock readLock = LOCK.readLock();
readLock.lock();
try{
//perform some read operation
} finally {
readLock.unlock();
}
}

//This method cannot run concurrently. While this method is running, other threads have to wait for the lock.
public void doWrite(){
Lock writeLock = LOCK.writeLock();
writeLock.lock();
try{
//perform some write operation
} finally {
writeLock.unlock();
}
}
private final ReadWriteLock LOCK = new ReentrantReadWriteLock();

//This method can run concurrently as often as needed but not concurrently with doWrite() (one has to wait for the other to finish)
public void doRead(){
Lock readLock = LOCK.readLock();
readLock.lock();
try{
//perform some read operation
} finally {
readLock.unlock();
}
}

//This method cannot run concurrently. While this method is running, other threads have to wait for the lock.
public void doWrite(){
Lock writeLock = LOCK.writeLock();
writeLock.lock();
try{
//perform some write operation
} finally {
writeLock.unlock();
}
}
3 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Because of these guarantees, enum instances can be safely compared with == instead of .equals(). They can also be used in switch statements, just like integer values. As of Java 14, they can also be used in switch expressions. Because the number of values is fixed and known at compile time, the cases can be exhaustive, meaning a default block is not required.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Finally, the JVM will ensure that no additional instances of the class exist beyond the declared values. In the "regular" DaysOfTheWeek class above, serialization can be used to circumvent the visibility restrictions on the constructor, which would result in instances that are not one of the 7 static final values. However, in the enum class, the JVM treats enum deserialization specially to ensure that the existing instances are returned.
Note that the JVM/JDK also blocks most reflective mechanisms from creating new enum instances. Be warned, though, that there are a couple of arcane mechanisms (notably, the soon-to-be-retired Unsafe class) that can actually break the normal guarantees around enum instances. These should never be used.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Second, enum classes implicitly extend an Enum base class, which provides methods for retrieving the enum value's name and ordinal. The Enum class also implements Comparable and Serializable, so all values of an enum can be compared, sorted, and serialized. Enum also exposes a static method to lookup any enum value by class and name. In addition to that, the compiler will generate a similar static method on each enum. To illustrate that last point, these two method calls are equivalent:
Enum.valueOf(MyEnum.class, "VALUE_1");
MyEnum.valueOf("VALUE_1"); // This method generated by the compiler for MyEnum
Enum.valueOf(MyEnum.class, "VALUE_1");
MyEnum.valueOf("VALUE_1"); // This method generated by the compiler for MyEnum
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
First, the enum is more compact, requiring less code to achieve a similar result. The enum's constants must be the first declarations in the class. The last one can be terminated with a semicolon, and then additional members -- including constructors, fields, and methods -- can be added to the enum, just like with any class. The only restriction is that constructors must be private; if the private access modifier is omitted, it will still be implied.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
As an example, compare the following enum....
public enum DaysOfTheWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
public enum DaysOfTheWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
.... with the following regular class....
public class DaysOfTheWeek {
public static final DaysOfTheWeek SUNDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek MONDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek TUESDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek WEDNESDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek THURSDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek FRIDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek SATURDAY = nwe DaysOfTheWeek();

private DaysOfTheWeek() {
}
}
public class DaysOfTheWeek {
public static final DaysOfTheWeek SUNDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek MONDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek TUESDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek WEDNESDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek THURSDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek FRIDAY = new DaysOfTheWeek();
public static final DaysOfTheWeek SATURDAY = nwe DaysOfTheWeek();

private DaysOfTheWeek() {
}
}
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
An enum is a special kind of Java class with a fixed set of values. They are similar in function to a regular class with a private constructor and a fixed number of public static final instances. However, enums have some advantages.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
An Enum is a Type of document, like a class or an interface. In this document you can write a number of values that can be use in the code. A code example can be: public enum numbers { ONE, TWO, THREE } And then you can call de enum numbers in youre code and be sure that the only numbers you can use are ONE, TWO and THREE thanks to this enum.... A practical example could be putting the extensions of files that your code accepts...
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Just like classes, enums can have fields and constructors but the constructors cannot be called except using the enum constants but a constructor must be called in the enum declaration:
public enum Weekday {
MONDAY("MON"), TUESDAY("TUE"), WEDNESDAY("WED"), THURSDAY("THU"), FRIDAY("FRI"),
SATURDAY("SAT"), SUNDAY("SUN");

private final String abbreviation;
private final boolean workday;

private Weekday(String abbreviation, boolean workday){
this.abbreviation = abbreviation;
this.workday = workday;
}

private Weekday(String abbreviation) {
this(abbreviation, true);
}

public boolean isWorkday(){
return workday;
}
public String getAbbreviation(){
return abbreviation;
}
}
public enum Weekday {
MONDAY("MON"), TUESDAY("TUE"), WEDNESDAY("WED"), THURSDAY("THU"), FRIDAY("FRI"),
SATURDAY("SAT"), SUNDAY("SUN");

private final String abbreviation;
private final boolean workday;

private Weekday(String abbreviation, boolean workday){
this.abbreviation = abbreviation;
this.workday = workday;
}

private Weekday(String abbreviation) {
this(abbreviation, true);
}

public boolean isWorkday(){
return workday;
}
public String getAbbreviation(){
return abbreviation;
}
}
Weekday endOfWorkWeek = Weekday.FRIDAY;
System.out.println(endOfWorkWeek.getAbbreviation() + " is workday: "+endOfWorkWeek.isWorkday());//FRI is workday: true

Weekday startOfWeekend = Weekday.SATURDAY;
System.out.println(startOfWeekend.getAbbreviation() + " is workday: "+startOfWeekend.isWorkday());//SAT is workday: false
Weekday endOfWorkWeek = Weekday.FRIDAY;
System.out.println(endOfWorkWeek.getAbbreviation() + " is workday: "+endOfWorkWeek.isWorkday());//FRI is workday: true

Weekday startOfWeekend = Weekday.SATURDAY;
System.out.println(startOfWeekend.getAbbreviation() + " is workday: "+startOfWeekend.isWorkday());//SAT is workday: false
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Enums are classes where all instances of the class are known at compile-time. An enum can be declared using the enum keyword with a list of all enum constants (list of the objects of the enum):
public enum SomeEnum {
FIRST, SECOND, THIRD
}
public enum SomeEnum {
FIRST, SECOND, THIRD
}
After an enum is declared, its instances can be obtained like regular constants and used like other objects:
SomeEnum enumValue = SomeEnum.SECOND;
System.out.println(enumValue);//SECOND
System.out.println(enumValue == SomeEnum.FIRST);//false
System.out.println(enumValue == SomeEnum.SECOND);//true
SomeEnum enumValue = SomeEnum.SECOND;
System.out.println(enumValue);//SECOND
System.out.println(enumValue == SomeEnum.FIRST);//false
System.out.println(enumValue == SomeEnum.SECOND);//true
All enums have an ordinal() method that can be used to get the index of the enum value in the declaration:
System.out.println(SomeEnum.FIRST.ordinal());//0
System.out.println(SomeEnum.SECOND.ordinal());//1
System.out.println(SomeEnum.THIRD.ordinal());//2
System.out.println(SomeEnum.FIRST.ordinal());//0
System.out.println(SomeEnum.SECOND.ordinal());//1
System.out.println(SomeEnum.THIRD.ordinal());//2
Similarly, the static method called values (which is present in every enum) returns an array of all values of that enum in the order of declaration. The value returned by ordinal() is the the index of that enum value in the array:
System.out.println(Arrays.toString(SomeEnum.values()));//[FIRST, SECOND, THIRD]
System.out.println(SomeEnum.values()[SomeEnum.THIRD.ordinal()]);//THIRD
System.out.println(Arrays.toString(SomeEnum.values()));//[FIRST, SECOND, THIRD]
System.out.println(SomeEnum.values()[SomeEnum.THIRD.ordinal()]);//THIRD
Apart from that, there is an implicit static method named valueOf in each enum class that can be used to get an enum value by name:
SomeEnum enumByName = SomeEnum.valueOf("FIRST");
System.out.println(enumByName == SomeEnum.FIRST);//true
SomeEnum enumByName = SomeEnum.valueOf("FIRST");
System.out.println(enumByName == SomeEnum.FIRST);//true
Enums always extend java.lang.Enum and cannot have any subclasses.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
Sometimes, it's also necessary to define some sort of order between objects. This can be done using the Comparable interface. A class can mark itself to be comparable to another class by implementing that interface and overriding the compareTo method. If firstObject and secondObject are equal (by the equals(Object) method), firstObject.compareTo(secondObject) as well as secondObject.compareTo(firstObject) should return 0. If firstObject is considered to be greater than secondObject, then firstObject.compareTo(secondObject) should return a value greater than 0 and secondObject.compareTo(firstObject) should return a value smaller than 0.
public final class SomeClass implements Comparable<SomeClass>{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}

@Override
public int compareTo(SomeClass other){
Objects.requireNonNull(other);
int someStringResult = someString.compareTo(other.someString);
if(someStringResult != 0){
return someStringResult;
}
return Integer.compare(someInt, other.someInt);
}
}
public final class SomeClass implements Comparable<SomeClass>{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}

@Override
public int compareTo(SomeClass other){
Objects.requireNonNull(other);
int someStringResult = someString.compareTo(other.someString);
if(someStringResult != 0){
return someStringResult;
}
return Integer.compare(someInt, other.someInt);
}
}
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 11/3/2024 in #❓︱qotw-answers
Week 98 — What is an enum?
The Object class provides an equals(Object) method that can be used to test for equality. To do that, one can override that method and write code for equality checks. If two objects are considered equal, firstObject.equals(secondObject) should return true, else it should return false. When overriding equals, one should make sure that a.equals(b) gives the same result as b.equals(a) (assuming that neither a nor b are null) and always also override hashCode and make sure that the hashCode() result is the same for all objects a and b where a.equals(b) is true.
public final class SomeClass{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}
}
public final class SomeClass{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}
}
SomeClass instance = new SomeClass("Hi", 1337);
System.out.println(instance.equals(new SomeClass("Hi", 1337)));//true
System.out.println(instance.equals(new SomeClass("Hi", 1338)));//false
System.out.println(instance.equals(new SomeClass("Ho", 1337)));//false
SomeClass instance = new SomeClass("Hi", 1337);
System.out.println(instance.equals(new SomeClass("Hi", 1337)));//true
System.out.println(instance.equals(new SomeClass("Hi", 1338)));//false
System.out.println(instance.equals(new SomeClass("Ho", 1337)));//false
The methods equals(Object) and hashCode() are used by many classes in the JDK for comparing objects, e.g. HashMap.
12 replies
JCHJava Community | Help. Code. Learn.
Created by JavaBot on 6/30/2024 in #❓︱qotw-answers
Week 80 — Which mechanisms does Java provide for comparing objects?
Sometimes, it's also necessary to define some sort of order between objects. This can be done using the Comparable interface. A class can mark itself to be comparable to another class by implementing that interface and overriding the compareTo method. If firstObject and secondObject are equal (by the equals(Object) method), firstObject.compareTo(secondObject) as well as secondObject.compareTo(firstObject) should return 0. If firstObject is considered to be greater than secondObject, then firstObject.compareTo(secondObject) should return a value greater than 0 and secondObject.compareTo(firstObject) should return a value smaller than 0.
public final class SomeClass implements Comparable<SomeClass>{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}

@Override
public int compareTo(SomeClass other){
Objects.requireNonNull(other);
int someStringResult = someString.compareTo(other.someString);
if(someStringResult != 0){
return someStringResult;
}
return Integer.compare(someInt, other.someInt);
}
}
public final class SomeClass implements Comparable<SomeClass>{
private String someString;
private int someInt;

public SomeClass(String someString, int someInt) {
this.someString = someString;
this.someInt = someInt;
}

@Override
public boolean equals(Object o){
return o instanceof SomeClass other &&
Objects.equals(someString, other.someString) &&
someInt == other.someInt;
}
@Override
public int hashCode(){
return Objects.hash(someString, someInt);
}

@Override
public int compareTo(SomeClass other){
Objects.requireNonNull(other);
int someStringResult = someString.compareTo(other.someString);
if(someStringResult != 0){
return someStringResult;
}
return Integer.compare(someInt, other.someInt);
}
}
15 replies