我试图根据字符串的2个组件以相反的顺序订购字符串列表(在Java中),第一个是月份(需要按时间顺序倒序),第二个是字符串开始时的整数值(不代表日期,因此它可能超过31)。例如:
List<String> dates = List.of("13 Dec", "44 Jun", "12 Dec", "103 Aug", "22 Sep", "23 Sep");
一旦订购应返回:
[13 Dec, 12 Dec, 23 Sep, 22 Sep, 103 Aug, 44 June]
谁能给我举个例子说明一下如何做到这一点?由于
这是一种方法。它使用了一些java。时间特征获取月份的值。
List<String> dates = new ArrayList<>(List.of("13 Dec",
"44 June", "12 Dec", "103 Aug", "22 Sep", "23 Sep"));
首先,使用DateTimeFormatter获取相应的整数月份。这避免了创建一个外部数据结构来保存月份。
Function<String, Integer> monNum = month -> DateTimeFormatter
.ofPattern("MMM").parse(month)
.get(ChronoField.MONTH_OF_YEAR);
然后构造一个比较器来比较两个字符串,首先按月,然后按数字,顺序倒序。
Comparator<String> comp =
Comparator.comparing((String str) -> str.split("\s+"),
Comparator.comparingInt((String[] a) -> monNum.apply(a[1]))
.thenComparing(a -> Integer.parseInt(a[0])))
.reversed();
dates.sort(comp);
System.out.println(dates);
打印
[13 Dec, 12 Dec, 23 Sep, 22 Sep, 103 Aug, 44 June]
你需要
- 拆分字符串
String[] split=string.split(" ");
- 测试第二个子字符串是否相同
split1[1].equals(split2[1])
- 如果相同,比较日期
Integer.parseInt(split1[0])<Integer.parseInt(split2[0]);
如果不是,则使用数组将月份名称与月份名称或类似名称进行比较。
private static final String[] MONTHS={"Jan","Feb",...};
private int getMonthNumeric(String abbr){
for(int i=0;i<MONTHS.length();i++){
if(abbr.equals(MONTHS[i]){
return i;
}
}
return -1;
}
//in your comparator
getMonthNumeric(split1[1])<getMonthNumeric(split1[1])
一个简单的比较器(忽略边缘情况)可能看起来像这样(使用lambda):
(a,b)->{
String[] split1=a.split(" ");
String[] split2=b.split(" ");
if(split1[1].equals(split2[1])){
return Integer.parseInt(split1[0])-Integer.parseInt(split2[0]);
}else{
return getMonthNumeric(split1[1])-getMonthNumeric(split1[1]);
}
}
对列表排序的代码可能如下所示:
private static final String[] MONTHS={"Jan","Feb",...};
private int getMonthNumeric(String abbr){
for(int i=0;i<MONTHS.length();i++){
if(abbr.equals(MONTHS[i]){
return i;
}
}
return -1;
}
//Where you want to sort the date:
Collections.sort(dates,(a,b)->{
String[] split1=a.split(" ");
String[] split2=b.split(" ");
if(split1[1].equals(split2[1])){
return Integer.parseInt(split1[0])-Integer.parseInt(split2[0]);
}else{
return getMonthNumeric(split1[1])-getMonthNumeric(split1[1]);
}
}
);
为#sorted stream方法提供您自己的Comparator。下面的示例比较月份索引。如果它们相等(差为0),则比较数字。查看文档中有关排序的信息。
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
/* [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, ] */
static String[] shortMonths = new DateFormatSymbols().getShortMonths();
static int getMonthIndex(String word) {
return Arrays.asList(shortMonths).indexOf(word.substring(0, Math.min(word.length(), 3)));
}
public static void main(String[] args) {
List<String> dates = Arrays.asList("13 Dec", "44 June", "12 Dec", "103 Aug", "22 Sep", "23 Sep");
dates = dates.stream().sorted((s1, s2) -> {
String[] a1 = s1.split(" ");
String[] a2 = s2.split(" ");
int comp = getMonthIndex(a2[1]) - (getMonthIndex(a1[1]));
return comp != 0 ? comp : a2[0].compareTo(a1[0]);
}).collect(Collectors.toList());
System.out.println(dates);
}
}
会产生[13 Dec, 12 Dec, 23 Sep, 22 Sep, 103 Aug, 44 June]