[Исходный ответ]
Ваш подход к использованию Map
может быть проблематичным c. Вы должны создать новый тип и использовать List
нового типа.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class MyType {
String playerKey;
Map<String, Object> map = new HashMap<String, Object>();
public MyType(String id, Map<String, Object> map) {
this.playerKey = id;
this.map = map;
}
public String getPlayerKey() {
return playerKey;
}
@Override
public String toString() {
return "playerKey=" + playerKey + ", pointsScored=" + map.get("pointsScored");
}
}
public class Main {
public static void main(String[] args) {
List<MyType> playersData = new ArrayList<MyType>();
playersData.add(new MyType("x1", Map.of("name", "john", "pointsScored", 50)));
playersData.add(new MyType("x11", Map.of("name", "harry", "pointsScored", 55)));
playersData.add(new MyType("x2", Map.of("name", "tina", "pointsScored", 60)));
playersData.add(new MyType("y1", Map.of("name", "richard", "pointsScored", 60)));
playersData.add(new MyType("y12", Map.of("name", "kim", "pointsScored", 45)));
playersData.add(new MyType("y3", Map.of("name", "karen", "pointsScored", 65)));
System.out.println("Orinally:");
playersData.stream().forEach(System.out::println);
playersData.sort(new Comparator<MyType>() {
@Override
public int compare(MyType t1, MyType t2) {
String s1 = t1.getPlayerKey();
String s2 = t2.getPlayerKey();
int compVal;
int n1 = 0, n2 = 0;
String sn1 = "", sn2 = "";
// Pattern to find a sequence of digits
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher;
matcher = pattern.matcher(s1);
if (matcher.find()) {
// Number from first string
sn1 = matcher.group();
n1 = Integer.valueOf(sn1);
}
matcher = pattern.matcher(s2);
if (matcher.find()) {
// Number from first string
sn2 = matcher.group();
n2 = Integer.valueOf(sn2);
}
// Compare the string part
compVal = s2.substring(0, s2.indexOf(sn2)).compareTo(s1.substring(0, s1.indexOf(sn1)));
// If string parts are same, compare the number parts
if (compVal == 0 && n1 != 0 && n2 != 0) {
compVal = Integer.compare(n2, n1);
}
return compVal;
}
});
System.out.println("\nSorted in reversed order of playerKey:");
playersData.stream().forEach(System.out::println);
}
}
[Обновить]
Вы можете использовать Map
следующим образом:
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* Comparator to compare alphanumeric words in the form of LETTERS+DIGITs e.g.
* A1, ABC123 etc.
*
*/
class MyComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
int compVal;
int n1 = 0, n2 = 0;
String sn1 = "", sn2 = "";
// Pattern to find a sequence of digits
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher;
matcher = pattern.matcher(s1);
if (matcher.find()) {
// Number from first string
sn1 = matcher.group();
n1 = Integer.valueOf(sn1);
}
matcher = pattern.matcher(s2);
if (matcher.find()) {
// Number from first string
sn2 = matcher.group();
n2 = Integer.valueOf(sn2);
}
// Compare the string part
compVal = s2.substring(0, s2.indexOf(sn2)).compareTo(s1.substring(0, s1.indexOf(sn1)));
// If string parts are same, compare the number parts
if (compVal == 0 && n1 != 0 && n2 != 0) {
compVal = Integer.compare(n2, n1);
}
return compVal;
}
}
public class Main {
public static void main(String[] args) {
Map<String, HashMap<String, Object>> playersDataMap = new HashMap<>();
for (int i = 1; i <= 10; i++) {
HashMap<String, Object> playerMap = new HashMap<>();
playerMap.put("name", "abc" + i);
playerMap.put("pointsScored", i * 10);
playersDataMap.put("x" + i, playerMap);
}
Map<String, HashMap<String, Object>> inversedPlayerDataMap = new TreeMap<>(new MyComparator());
inversedPlayerDataMap.putAll(playersDataMap);
for (Map.Entry<String, HashMap<String, Object>> entry : inversedPlayerDataMap.entrySet()) {
System.out
.println("playerKey=" + entry.getKey() + ", pointsScored=" + entry.getValue().get("pointsScored"));
}
}
}
Вывод:
playerKey=x10, pointsScored=100
playerKey=x9, pointsScored=90
playerKey=x8, pointsScored=80
playerKey=x7, pointsScored=70
playerKey=x6, pointsScored=60
playerKey=x5, pointsScored=50
playerKey=x4, pointsScored=40
playerKey=x3, pointsScored=30
playerKey=x2, pointsScored=20
playerKey=x1, pointsScored=10