Java 自定义大小字符串比较器
Java Custom Size String Comparator
我有以下字符串:
50ml,100g,3.5ml,10g,0.4g,320ml,我需要按如下顺序订购:
0.4g,10g,100g,3.5ml,50ml,320ml
标准是按字母顺序排列尺码类型(g 在 m 之前),然后是实际尺码 ASCENDANT(0.4 10g 100g)
如何使用比较器实现此目的?
protected int compareInstances(String instance1, String instance2) {
return 0;
}
这里采用的最简单(但不是最漂亮)的方法可能是将值简单地拆分为前缀(实际值)和后缀(测量值),然后分别进行比较。
所以我实现了一个Comparator<String>
,它将给定的值拆分为前缀和后缀,然后首先按字母顺序比较后缀。 (免责声明:大写字母将被视为比小写字母“更小”)如果它们相等,则比较前缀值。
这是一个具有所描述逻辑的小示例:
import java.util.Arrays;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
String input = "50ml,100g,3.5ml,10g,0.4g,320ml,32.3a,3.6ml";
String[] splitInput = input.split(",");
System.out.println("Before:\t" + Arrays.toString(splitInput));
Arrays.sort(splitInput, new MyComparator());
System.out.println("After:\t" + Arrays.toString(splitInput));
}
static class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
// extract the suffix by removing the digits and dots
String suffix1 = o1.replaceAll("[\d\.]", "");
String suffix2 = o2.replaceAll("[\d\.]", "");
if (suffix1.compareTo(suffix2) != 0) {
return suffix1.compareTo(suffix2); // String#compareTo
}
// extract the prefix by removing the characters
double value1 = Double.parseDouble(o1.replaceAll("[A-Za-z]", ""));
double value2 = Double.parseDouble(o2.replaceAll("[A-Za-z]", ""));
// compare the double values
return (int) Double.compare(value1, value2);
}
}
}
输出:
Before: [50ml, 100g, 3.5ml, 10g, 0.4g, 320ml, 32.3a, 3.6ml]
After: [32.3a, 0.4g, 10g, 100g, 3.5ml, 3.6ml, 50ml, 320ml]
有很多方法可以做到这一点。我会编写一个简单的排序方法来排序和 return 排序后的字符串,而不是单独的比较器。当然,return值可以修改为return任何数据结构。
String s = "50ml,100g,3.5ml,10g,0.4g,320ml";
String result = sort(s);
System.out.println(result);
版画
0.4g,10g,100g,3.5ml,50ml,320ml
- 此方法首先在逗号分隔符处拆分字符串。
- 然后它流式传输这些字符串,首先,将它们拆分为数字和字母(我认为最好在比较器之外执行此操作以减少重复拆分)。
- 然后对值进行排序,首先是单位,然后是数量,然后重新组合成它们的原始格式。
public static String sort(String s) {
String[] amts = s.split(",");
return Arrays.stream(amts)
.map(amt -> amt.trim().toLowerCase().split("(?<=\d)(?=\p{Lower})"))
.sorted(Comparator.comparing((String[] arr) -> arr[1])
.thenComparing(
arr -> Double.parseDouble(arr[0])))
.map(arr -> arr[0] + arr[1])
.collect(Collectors.joining(","));
}
- 如果需要数组,请将 return 类型更改为
String[]
- 并将
.collect(Collectors.joining(","));
更改为.toArray(String[]::new);
我有以下字符串:
50ml,100g,3.5ml,10g,0.4g,320ml,我需要按如下顺序订购:
0.4g,10g,100g,3.5ml,50ml,320ml
标准是按字母顺序排列尺码类型(g 在 m 之前),然后是实际尺码 ASCENDANT(0.4 10g 100g)
如何使用比较器实现此目的?
protected int compareInstances(String instance1, String instance2) {
return 0;
}
这里采用的最简单(但不是最漂亮)的方法可能是将值简单地拆分为前缀(实际值)和后缀(测量值),然后分别进行比较。
所以我实现了一个Comparator<String>
,它将给定的值拆分为前缀和后缀,然后首先按字母顺序比较后缀。 (免责声明:大写字母将被视为比小写字母“更小”)如果它们相等,则比较前缀值。
这是一个具有所描述逻辑的小示例:
import java.util.Arrays;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
String input = "50ml,100g,3.5ml,10g,0.4g,320ml,32.3a,3.6ml";
String[] splitInput = input.split(",");
System.out.println("Before:\t" + Arrays.toString(splitInput));
Arrays.sort(splitInput, new MyComparator());
System.out.println("After:\t" + Arrays.toString(splitInput));
}
static class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
// extract the suffix by removing the digits and dots
String suffix1 = o1.replaceAll("[\d\.]", "");
String suffix2 = o2.replaceAll("[\d\.]", "");
if (suffix1.compareTo(suffix2) != 0) {
return suffix1.compareTo(suffix2); // String#compareTo
}
// extract the prefix by removing the characters
double value1 = Double.parseDouble(o1.replaceAll("[A-Za-z]", ""));
double value2 = Double.parseDouble(o2.replaceAll("[A-Za-z]", ""));
// compare the double values
return (int) Double.compare(value1, value2);
}
}
}
输出:
Before: [50ml, 100g, 3.5ml, 10g, 0.4g, 320ml, 32.3a, 3.6ml]
After: [32.3a, 0.4g, 10g, 100g, 3.5ml, 3.6ml, 50ml, 320ml]
有很多方法可以做到这一点。我会编写一个简单的排序方法来排序和 return 排序后的字符串,而不是单独的比较器。当然,return值可以修改为return任何数据结构。
String s = "50ml,100g,3.5ml,10g,0.4g,320ml";
String result = sort(s);
System.out.println(result);
版画
0.4g,10g,100g,3.5ml,50ml,320ml
- 此方法首先在逗号分隔符处拆分字符串。
- 然后它流式传输这些字符串,首先,将它们拆分为数字和字母(我认为最好在比较器之外执行此操作以减少重复拆分)。
- 然后对值进行排序,首先是单位,然后是数量,然后重新组合成它们的原始格式。
public static String sort(String s) {
String[] amts = s.split(",");
return Arrays.stream(amts)
.map(amt -> amt.trim().toLowerCase().split("(?<=\d)(?=\p{Lower})"))
.sorted(Comparator.comparing((String[] arr) -> arr[1])
.thenComparing(
arr -> Double.parseDouble(arr[0])))
.map(arr -> arr[0] + arr[1])
.collect(Collectors.joining(","));
}
- 如果需要数组,请将 return 类型更改为
String[]
- 并将
.collect(Collectors.joining(","));
更改为.toArray(String[]::new);