分组字符串-Java

时间:2018-10-05 00:01:39

标签: java string

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

3 个答案:

答案 0 :(得分:3)

听起来您想根据两个条件进行排序:

  • 每个列表项中的前三个字符,和
  • 每个列表项其余部分的内容,例如,首先显示Letter.pdf。

一个比较老套的合理解决方案是实现自定义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)

根据您的描述-建议将问题分解为两个子问题:

  • 第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 {

    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);
    }
}