分组字符串 - Java

我有一个 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);

        }


收到一只叮咚
浏览 178回答 3
3回答

开满天机

听起来您想根据两个标准进行排序:每个列表项中的前三个字符,以及每个列表项的其余内容,例如 Letter.pdf 首先出现。一个老派的合理解决方案是实现 custom&nbsp;java.util.Comparator,并将其用作排序的基础:public static List<String> sortOldSchool(List<String> list){&nbsp; &nbsp; Comparator<String> comparator = new Comparator<String>(){&nbsp; &nbsp; &nbsp; &nbsp; private static final String LETTER = "Letter.pdf";&nbsp; &nbsp; &nbsp; &nbsp; public int compare(String orange, String apple){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String ostart = orange.substring(0,3);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String astart = apple.substring(0,3);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ostart.equals(astart)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (orange.endsWith(LETTER)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (apple.endsWith(LETTER)) ? 0 : -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else return (apple.endsWith(LETTER)) ? 1 : orange.compareTo(apple);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else return ostart.compareTo(astart);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };&nbsp; &nbsp; Collections.sort(list, comparator);&nbsp; &nbsp; return list;}一种更现代的方法是利用从 Java 8 开始可用的新功能范式:public static List<String> sortFunctional(List<String> list){&nbsp; &nbsp; Comparator<String> firstThree= Comparator.comparing(item -> item.substring(0,3));&nbsp; &nbsp; Comparator<String> letter = Comparator.comparing(item -> (!item.endsWith("Letter.pdf")));&nbsp; &nbsp; return list.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .sorted(firstThree.thenComparing(letter))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());}&nbsp; &nbsp;&nbsp;

Smart猫小萌

根据您的描述 - 我建议将问题分解为两个子问题:步骤 1:将值组织到它们的前缀组中第 2 步:对每个前缀组中的值进行排序,确保值“_Letter.pdf”排在第一位。我提供了一个代码示例来演示以下每个步骤: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 {&nbsp; &nbsp; List<String> values = Arrays.asList(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_Letter.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_Others.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_More.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Second.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Letter.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Third.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Fourth.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_File.pdf");&nbsp; &nbsp; List<String> expected = Arrays.asList(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_Letter.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_Others.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_More.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "123_File.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Letter.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Second.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Third.pdf",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "222_Fourth.pdf"&nbsp; &nbsp; );&nbsp; &nbsp; @Test&nbsp; &nbsp; public void sort() {&nbsp; &nbsp; &nbsp; &nbsp; // Basic function to group the values by the prefix&nbsp; &nbsp; &nbsp; &nbsp; Collector<String, ?, Map<String, List<String>>> groupByPrefix = Collectors.groupingBy(c -> c.substring(0, 3));&nbsp; &nbsp; &nbsp; &nbsp; // Basic function to sort the groups with _Letter.pdf first&nbsp; &nbsp; &nbsp; &nbsp; Function<List<String>, Stream<? extends String>> sortPrefixGroups = v ->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v.stream().sorted(Comparator.comparing(i -> !i.endsWith("_Letter.pdf")));&nbsp; &nbsp; &nbsp; &nbsp; // Step 1: Organise the values into their prefix groups&nbsp; &nbsp; &nbsp; &nbsp; Map<String, List<String>> groupedByPrefix = new TreeMap<>(values.stream().collect(groupByPrefix));&nbsp; &nbsp; &nbsp; &nbsp; // Step 2: Sort each of the prefix groups and recombine them back into a list to maintain their internal order&nbsp; &nbsp; &nbsp; &nbsp; List<String> collect = groupedByPrefix.entrySet().stream().map(Map.Entry::getValue).flatMap(sortPrefixGroups).collect(toList());&nbsp; &nbsp; &nbsp; &nbsp; Assert.assertEquals(expected, collect);&nbsp; &nbsp; &nbsp; &nbsp; //Print just for fun&nbsp; &nbsp; &nbsp; &nbsp; collect.forEach(System.out::println);&nbsp; &nbsp; }}

繁星点点滴滴

如何使用HashMap:HashMap<String, List<String>> hashMap = new HashMap<String, List<String>>();现在,遍历哈希图并添加元素:if (!hashMap.containsKey(listItem.substring(0,2)) {&nbsp; &nbsp; List<String> items = new ArrayList<String>();&nbsp; &nbsp; items.add(listItem);&nbsp; &nbsp; hashMap.put(listItem.substring(0,2), items);} else {&nbsp; &nbsp; hashMap.get(listItem.substring(0,2)).add(items);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java