我有一个ArrayList。我想对类似的项目进行分组,以便letter.pdf是每个分组中的第一个。例如:
123_Letter.pdf
123_Others.pdf
123_More.pdf
222_Second.pdf
222_Letter.pdf
222_Third.pdf
222_Fourth.pdf
123_File.pdf
输出应为:
**123_Letter.pdf**
123_Others.pdf
123_More.pdf
123_File.pdf
**222_Letter.pdf**
222_Second.pdf
222_Third.pdf
222_Fourth.pdf
每个组中其他元素的顺序无关紧要。列表中有3000多个元素。如您所见,仅排序没有多大帮助。
我尝试过类似的操作,但缺少最后一个元素123_File.pdf。有更好的方法吗?请帮忙。
String root = list.get(0).substring(0,4);
ArrayList<String> al = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
while (list.get(i).substring(0, 4).equals(root)) {
if (list.get(i).endsWith("etter.pdf")) {
al.add(0, list.get(i));
i++;
} else {
al.add(list.get(i));
i++;
}
}
System.out.println(al);
al = new ArrayList<>();
root = list.get(i).substring(0, 4);
}
答案 0 :(得分:3)
听起来您想根据两个条件进行排序:
一个比较老套的合理解决方案是实现自定义java.util.Comparator
,并将其用作排序的基础:
public static List<String> sortOldSchool(List<String> list){
Comparator<String> comparator = new Comparator<String>(){
private static final String LETTER = "Letter.pdf";
public int compare(String orange, String apple){
String ostart = orange.substring(0,3);
String astart = apple.substring(0,3);
if (ostart.equals(astart)){
if (orange.endsWith(LETTER)){
return (apple.endsWith(LETTER)) ? 0 : -1;
}
else return (apple.endsWith(LETTER)) ? 1 : orange.compareTo(apple);
}
else return ostart.compareTo(astart);
}
};
Collections.sort(list, comparator);
return list;
}
更现代的方法是利用从Java 8开始可用的新功能范例:
public static List<String> sortFunctional(List<String> list){
Comparator<String> firstThree= Comparator.comparing(item -> item.substring(0,3));
Comparator<String> letter = Comparator.comparing(item -> (!item.endsWith("Letter.pdf")));
return list.stream()
.sorted(firstThree.thenComparing(letter))
.collect(Collectors.toList());
}
答案 1 :(得分:0)
如何使用Give an Integer: NOOO
You need Integer!
Give an Integer: 45
Give an Integer: again?
You need Integer!
Give an Integer: okay
You need Integer!
Give an Integer: 4
The entered integers are: 45 4
:
HashMap
现在,遍历哈希图并添加元素:
HashMap<String, List<String>> hashMap = new HashMap<String, List<String>>();
答案 2 :(得分:0)
根据您的描述-建议将问题分解为两个子问题:
我提供了一个代码示例,演示了以下每个步骤:
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class StackoverflowTest {
List<String> values = Arrays.asList(
"123_Letter.pdf",
"123_Others.pdf",
"123_More.pdf",
"222_Second.pdf",
"222_Letter.pdf",
"222_Third.pdf",
"222_Fourth.pdf",
"123_File.pdf");
List<String> expected = Arrays.asList(
"123_Letter.pdf",
"123_Others.pdf",
"123_More.pdf",
"123_File.pdf",
"222_Letter.pdf",
"222_Second.pdf",
"222_Third.pdf",
"222_Fourth.pdf"
);
@Test
public void sort() {
// Basic function to group the values by the prefix
Collector<String, ?, Map<String, List<String>>> groupByPrefix = Collectors.groupingBy(c -> c.substring(0, 3));
// Basic function to sort the groups with _Letter.pdf first
Function<List<String>, Stream<? extends String>> sortPrefixGroups = v ->
v.stream().sorted(Comparator.comparing(i -> !i.endsWith("_Letter.pdf")));
// Step 1: Organise the values into their prefix groups
Map<String, List<String>> groupedByPrefix = new TreeMap<>(values.stream().collect(groupByPrefix));
// Step 2: Sort each of the prefix groups and recombine them back into a list to maintain their internal order
List<String> collect = groupedByPrefix.entrySet().stream().map(Map.Entry::getValue).flatMap(sortPrefixGroups).collect(toList());
Assert.assertEquals(expected, collect);
//Print just for fun
collect.forEach(System.out::println);
}
}