Skip to content

Migrate to Java 21 and Refactor for Modern Java Syntax#11

Merged
marevol merged 2 commits intomasterfrom
feature/java21-upgrade
Jul 24, 2025
Merged

Migrate to Java 21 and Refactor for Modern Java Syntax#11
marevol merged 2 commits intomasterfrom
feature/java21-upgrade

Conversation

@marevol
Copy link
Contributor

@marevol marevol commented Jul 24, 2025

This PR upgrades the project to Java 21 by updating the Maven build configuration and enhancing source code using modern Java syntax features, including pattern matching and enhanced switch expressions. The README has been significantly extended to reflect these changes, highlighting new features and Java 21 support. Additionally, CollectionsUtil has been extended to support Java 21’s SequencedCollection and SequencedMap interfaces.

@marevol marevol requested a review from Copilot July 24, 2025 00:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the project from Java 17 to Java 21, modernizing the codebase with contemporary Java syntax and features. The upgrade leverages pattern matching, enhanced switch expressions, and sequenced collections to improve code readability and performance.

  • Migrates build configuration and CI pipeline to Java 21
  • Refactors legacy if-else chains and switch statements to use modern pattern matching and switch expressions
  • Adds support for Java 21's SequencedCollection and SequencedMap interfaces in CollectionsUtil
  • Updates project documentation to reflect Java 21 features and enhanced capabilities

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
pom.xml Updates Maven compiler plugin to target Java 21 and bumps version to 0.7.0-SNAPSHOT
.github/workflows/maven.yml Updates CI pipeline to use JDK 21 instead of JDK 17
JsonUtil.java Replaces traditional switch statement with modern switch expression for JSON character escaping
GenericsUtil.java Converts if-else chains to pattern matching switch expressions for type handling
StringConversionUtil.java Modernizes type conversion logic and character mapping with switch expressions
LongConversionUtil.java Refactors object-to-long conversion methods using pattern matching
IntegerConversionUtil.java Updates object-to-integer conversion with modern switch syntax
BooleanConversionUtil.java Simplifies boolean conversion logic with nested switch expressions
CollectionsUtil.java Adds new utility methods supporting Java 21's sequenced collections
README.md Comprehensive documentation update highlighting Java 21 features and modern capabilities

if (value == null) {
return null;
}
if(value==null){return null;}
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Missing spaces around operators and braces. Should be formatted as 'if (value == null) { return null; }' to maintain consistent code style.

Suggested change
if(value==null){return null;}
if (value == null) { return null; }

Copilot uses AI. Check for mistakes.
char c;
final int len = value.length();
final StringBuilder buf = new StringBuilder(len * 2);
char c;final int len=value.length();final StringBuilder buf=new StringBuilder(len*2);
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Multiple variable declarations on a single line with inconsistent spacing. Should be separated into individual lines with proper spacing for better readability.

Suggested change
char c;final int len=value.length();final StringBuilder buf=new StringBuilder(len*2);
char c;
final int len = value.length();
final StringBuilder buf = new StringBuilder(len * 2);

Copilot uses AI. Check for mistakes.
}
}
return buf.toString();
for(int i=0;i<len;i++){c=value.charAt(i);String escaped=switch(c){case'\\','"'->"\\"+c;case'/'->"\\/";case'\b'->"\\b";case'\t'->"\\t";case'\n'->"\\n";case'\f'->"\\f";case'\r'->"\\r";default->c<' '?"\\u"+"0".repeat(4-Integer.toHexString(c).length())+Integer.toHexString(c):String.valueOf(c);};buf.append(escaped);}return buf.toString();
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entire method logic compressed into a single line, making it extremely difficult to read and debug. This should be properly formatted with line breaks and spacing.

Suggested change
for(int i=0;i<len;i++){c=value.charAt(i);String escaped=switch(c){case'\\','"'->"\\"+c;case'/'->"\\/";case'\b'->"\\b";case'\t'->"\\t";case'\n'->"\\n";case'\f'->"\\f";case'\r'->"\\r";default->c<' '?"\\u"+"0".repeat(4-Integer.toHexString(c).length())+Integer.toHexString(c):String.valueOf(c);};buf.append(escaped);}return buf.toString();
for (int i = 0; i < len; i++) {
c = value.charAt(i);
String escaped = switch (c) {
case '\\', '"' -> "\\" + c;
case '/' -> "\\/";
case '\b' -> "\\b";
case '\t' -> "\\t";
case '\n' -> "\\n";
case '\f' -> "\\f";
case '\r' -> "\\r";
default -> c < ' '
? "\\u" + "0".repeat(4 - Integer.toHexString(c).length()) + Integer.toHexString(c)
: String.valueOf(c);
};
buf.append(escaped);
}
return buf.toString();

Copilot uses AI. Check for mistakes.
} else {
return value.toString();
}
return switch(value){case null->null;case String s->s;case java.util.Date d->toString(d,pattern);case Number n->toString(n,pattern);case byte[]bytes->Base64Util.encode(bytes);default->value.toString();};
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Complex switch expression compressed into a single line. Should be formatted with proper line breaks and spacing for better readability.

Suggested change
return switch(value){case null->null;case String s->s;case java.util.Date d->toString(d,pattern);case Number n->toString(n,pattern);case byte[]bytes->Base64Util.encode(bytes);default->value.toString();};
return switch (value) {
case null -> null;
case String s -> s;
case java.util.Date d -> toString(d, pattern);
case Number n -> toString(n, pattern);
case byte[] bytes -> Base64Util.encode(bytes);
default -> value.toString();
};

Copilot uses AI. Check for mistakes.
} else {
return toLong(o.toString());
}
return switch(o){case null->null;case Long l->l;case Number n->n.longValue();case String s->toLong(s);case java.util.Date d->pattern!=null?Long.valueOf(new SimpleDateFormat(pattern).format(d)):d.getTime();case Boolean b->b?1L:0L;default->toLong(o.toString());};
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Complex switch expression compressed into a single line. Should be formatted with proper line breaks and spacing for better readability.

Suggested change
return switch(o){case null->null;case Long l->l;case Number n->n.longValue();case String s->toLong(s);case java.util.Date d->pattern!=null?Long.valueOf(new SimpleDateFormat(pattern).format(d)):d.getTime();case Boolean b->b?1L:0L;default->toLong(o.toString());};
return switch (o) {
case null -> null;
case Long l -> l;
case Number n -> n.longValue();
case String s -> toLong(s);
case java.util.Date d -> {
if (pattern != null) {
return Long.valueOf(new SimpleDateFormat(pattern).format(d));
} else {
return d.getTime();
}
}
case Boolean b -> b ? 1L : 0L;
default -> toLong(o.toString());
};

Copilot uses AI. Check for mistakes.
} else {
return Boolean.TRUE;
}
return switch(o){case null->null;case Boolean b->b;case Number n->n.intValue()!=0;case String s->switch(s.toLowerCase()){case"true"->Boolean.TRUE;case"false","0"->Boolean.FALSE;default->Boolean.TRUE;};default->Boolean.TRUE;};
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Complex nested switch expression compressed into a single line. Should be formatted with proper line breaks and spacing for better readability.

Suggested change
return switch(o){case null->null;case Boolean b->b;case Number n->n.intValue()!=0;case String s->switch(s.toLowerCase()){case"true"->Boolean.TRUE;case"false","0"->Boolean.FALSE;default->Boolean.TRUE;};default->Boolean.TRUE;};
return switch (o) {
case null -> null;
case Boolean b -> b;
case Number n -> n.intValue() != 0;
case String s -> switch (s.toLowerCase()) {
case "true" -> Boolean.TRUE;
case "false", "0" -> Boolean.FALSE;
default -> Boolean.TRUE;
};
default -> Boolean.TRUE;
};

Copilot uses AI. Check for mistakes.
* @since Java 21
*/
public static <E> E getFirst(final SequencedCollection<E> collection) {
return collection.isEmpty() ? null : collection.getFirst();
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will throw NoSuchElementException if the collection is empty, because getFirst() throws this exception when called on an empty SequencedCollection. The isEmpty() check should prevent calling getFirst() when empty.

Suggested change
return collection.isEmpty() ? null : collection.getFirst();
if (collection.isEmpty()) {
return null;
}
try {
return collection.getFirst();
} catch (NoSuchElementException e) {
return null;
}

Copilot uses AI. Check for mistakes.
* @since Java 21
*/
public static <E> E getLast(final SequencedCollection<E> collection) {
return collection.isEmpty() ? null : collection.getLast();
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will throw NoSuchElementException if the collection is empty, because getLast() throws this exception when called on an empty SequencedCollection. The isEmpty() check should prevent calling getLast() when empty.

Suggested change
return collection.isEmpty() ? null : collection.getLast();
if (collection == null || collection.isEmpty()) {
return null;
}
return collection.getLast();

Copilot uses AI. Check for mistakes.
* @since Java 21
*/
public static <K, V> Map.Entry<K, V> firstEntry(final SequencedMap<K, V> map) {
return map.isEmpty() ? null : map.firstEntry();
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will throw NoSuchElementException if the map is empty, because firstEntry() throws this exception when called on an empty SequencedMap. The isEmpty() check should prevent calling firstEntry() when empty.

Suggested change
return map.isEmpty() ? null : map.firstEntry();
try {
return map.firstEntry();
} catch (NoSuchElementException e) {
return null;
}

Copilot uses AI. Check for mistakes.
* @since Java 21
*/
public static <K, V> Map.Entry<K, V> lastEntry(final SequencedMap<K, V> map) {
return map.isEmpty() ? null : map.lastEntry();
Copy link

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will throw NoSuchElementException if the map is empty, because lastEntry() throws this exception when called on an empty SequencedMap. The isEmpty() check should prevent calling lastEntry() when empty.

Suggested change
return map.isEmpty() ? null : map.lastEntry();
synchronized (map) {
return map.isEmpty() ? null : map.lastEntry();
}

Copilot uses AI. Check for mistakes.
@marevol marevol merged commit 9187b76 into master Jul 24, 2025
1 check passed
@marevol marevol changed the title Title: Migrate to Java 21 and Refactor for Modern Java Syntax Migrate to Java 21 and Refactor for Modern Java Syntax Jul 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant