分组字符串-Java

分组字符串-Java,java,string,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

我有一个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);
        }
stringroot=list.get(0).substring(0,4);
ArrayList al=新的ArrayList();
对于(int i=0;i
使用HashMap怎么样

HashMap<String, List<String>> hashMap = new HashMap<String, List<String>>();
HashMap HashMap=newhashmap();
现在,迭代hashmap并添加元素:

if (!hashMap.containsKey(listItem.substring(0,2)) {
    List<String> items = new ArrayList<String>();
    items.add(listItem);

    hashMap.put(listItem.substring(0,2), items);
} else {
    hashMap.get(listItem.substring(0,2)).add(items);
}
if(!hashMap.containsKey(listItem.substring(0,2)){
列表项=新建ArrayList();
添加(列表项);
put(listItem.substring(0,2),items);
}否则{
get(listItem.substring(0,2)).add(items);
}

使用HashMap怎么样

HashMap<String, List<String>> hashMap = new HashMap<String, List<String>>();
HashMap HashMap=newhashmap();
现在,迭代hashmap并添加元素:

if (!hashMap.containsKey(listItem.substring(0,2)) {
    List<String> items = new ArrayList<String>();
    items.add(listItem);

    hashMap.put(listItem.substring(0,2), items);
} else {
    hashMap.get(listItem.substring(0,2)).add(items);
}
if(!hashMap.containsKey(listItem.substring(0,2)){
列表项=新建ArrayList();
添加(列表项);
put(listItem.substring(0,2),items);
}否则{
get(listItem.substring(0,2)).add(items);
}

听起来您需要根据两个标准进行排序:

  • 每个列表项中的前三个字符,以及
  • 每个列表项其余部分的内容,例如首先显示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;
}
公共静态列表排序学校(列表){
比较器比较器=新比较器(){
私有静态最终字符串LETTER=“LETTER.pdf”;
公共整数比较(橙色字符串、苹果字符串){
字符串ostart=橙色。子字符串(0,3);
字符串astart=apple.substring(0,3);
if(ostart.等于(astart)){
if(橙色尾端(字母)){
返回(带字母的苹果尾端)?0:-1;
}
else返回(apple.endsWith(字母))?1:橙色。与(苹果)相比;
}
否则返回ostart.compareTo(astart);
}
};
集合。排序(列表、比较);
退货清单;
}
更现代的方法是利用从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());
}    
公共静态列表排序功能(列表){
比较器firstThree=比较器比较(项->项子串(0,3));
比较器字母=比较器。比较(item->(!item.endsWith(“letter.pdf”));
return list.stream()
.排序(前三个,然后比较(字母))
.collect(Collectors.toList());
}    

听起来您需要根据两个标准进行排序:

  • 每个列表项中的前三个字符,以及
  • 每个列表项其余部分的内容,例如首先显示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;
}
公共静态列表排序学校(列表){
比较器比较器=新比较器(){
私有静态最终字符串LETTER=“LETTER.pdf”;
公共整数比较(橙色字符串、苹果字符串){
字符串ostart=橙色。子字符串(0,3);
字符串astart=apple.substring(0,3);
if(ostart.等于(astart)){
if(橙色尾端(字母)){
返回(带字母的苹果尾端)?0:-1;
}
else返回(apple.endsWith(字母))?1:橙色。与(苹果)相比;
}
否则返回ostart.compareTo(astart);
}
};
集合。排序(列表、比较);
退货清单;
}
更现代的方法是利用从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());
}    
公共静态列表排序功能(列表){
比较器firstThree=比较器比较(项->项子串(0,3));
比较器字母=比较器。比较(item->(!item.endsWith(“letter.pdf”));
return list.stream()
.排序(前三个,然后比较(字母))
.collect(Collectors.toList());
}    

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

  • 步骤1:将值组织到前缀组中
  • 步骤2:对每个前缀组中的值进行排序,确保值“\u 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);
    }
}
import java.util.*;
导入java.util.function.function;
导入java.util.stream.Collector;
导入java.util.stream.collector;
导入java.util.stream.stream;
导入静态java.util.stream.Collectors.toList;
公共类堆栈溢出测试{
列表值=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”);
预期列表=Arrays.asList(
“123_Letter.pdf”,
“123_Others.pdf”,
“123_More.pdf”,
“123_File.pdf”,
“222_Letter.pdf”,
“222_Second.pdf”,