There are a couple of problems within your code:
You stop iterating before reaching the last character, instead of iterating till length/2 included (you need to check the beginning and end without overlapping so no need to iterate till the end or almost).
You substringEnd should start from the right side, so it should look like string.substring(string.length() - i);.
Here is a fixed implementation:
public static void main(String[] args) {
List<String> listTest = List.of("abXYab", "xx", "xxx", "xxxx", "javaXYZjava", "javajava", "Hello! and Hello!", "x", "", "abcd", "mymmy");
String substringFront, substringEnd, longestMatch;
for (String string : listTest) {
longestMatch = "";
for (int i = 1; i <= string.length() / 2; i++) {
substringFront = string.substring(0, i);
substringEnd = string.substring(string.length() - i);
if (substringEnd.equals(substringFront) && substringEnd.length() > longestMatch.length()) {
longestMatch = substringEnd;
}
}
if (!listTest.equals("")) {
System.out.printf("%s => %s%n", string, longestMatch);
} else {
System.out.printf("%s => null%n", string);
}
}
}
Here is a link to test the code above:
https://www.jdoodle.com/iembed/v0/rEO
However, to make it more concise you could use a regex which uses a capturing group with a greedy quantifier to match at the beginning of the string and make sure that what has been captured at the beginning matches also at the end.
^(.+)(.*)\1$
Here is a link to test the regex:
https://regex101.com/r/cgowDQ/1
This could be written in Java like so:
public static void main(String[] args) {
List<String> listTest = List.of("abXYab", "xx", "xxx", "xxxx", "javaXYZjava", "javajava", "Hello! and Hello!", "x", "", "abcd", "mymmy");
Pattern pattern = Pattern.compile("^(.+)(.*)\\1$");
Matcher matcher;
for (String s : listTest) {
matcher = pattern.matcher(s);
if (matcher.find()) {
System.out.printf("%s => %s%n", s, matcher.group(1));
} else {
System.out.printf("%s => null%n", s);
}
}
}
Here you can test the code above:
https://www.jdoodle.com/iembed/v0/rEK