首页 > 解决方案 > 根据给定的前缀对字符串列表进行排序

问题描述

我正在尝试通过定义一些前缀根据自定义排序顺序对字符串列表进行排序。结果应根据前缀的顺序进行排序,并且不匹配的条目应位于列表的末尾。当多个字符串以相同的前缀开头或其余部分有多个条目时,应按字母顺序排序。

已经尝试了基于来自另一个线程的解决方案的自定义比较器如何根据自定义顺序对 java 列表进行排序。但是我现在被困在我要求的最后一部分,即把没有前缀的剩余条目放在列表的末尾。

final Comparator<String> comparator = new PrefixComparator(Arrays.asList("java.", "javax.", "org."));
final ArrayList<String> imports = Lists.newArrayList("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Test", "org.testng.annotations.Optional", "de.bigmichi1.test.ClassB");

Collections.shuffle(imports);

imports.sort(comparator);

Assertions.assertThat(imports).containsExactly("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Optional","org.testng.annotations.Test", "de.bigmichi1.test.ClassB");
public class PrefixComparator implements Comparator<String>, Serializable {
    private static final long serialVersionUID = -5748758614646881440L;
    private final List<String> customOrder;

    public PrefixComparator(@Nonnull final List<String> customOrder) {
        this.customOrder = customOrder;
    }

    @Override
    public int compare(final String o1,
            final String o2) {
        int order1 = -1;
        int order2 = -1;
        String remainder1 = "";
        String remainder2 = "";
        for (final String prefix : customOrder) {
            if (o1.startsWith(prefix)) {
                order1 = customOrder.indexOf(prefix);
                remainder1 = o1.substring(prefix.length());
            }
            if (o2.startsWith(prefix)) {
                order2 = customOrder.indexOf(prefix);
                remainder2 = o2.substring(prefix.length());
            }
        }
        if (order1 == order2) {
            return remainder1.compareTo(remainder2);
        } else {
            return order1 - order2;
        }
    }
}

标签: java

解决方案


这是我的做法:

import java.util.*;

public class Test
{
    public static void main(String[] args) {
        List<String> prefix = Arrays.asList("java.", "javax.", "org.");
        List<String> imports = Arrays.asList("org.testng.annotations.Test", "java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Optional", "de.bigmichi1.test.ClassB");
        Collections.sort(imports, new Comparator<String>(){
            int prefix1Index = Integer.MAX_VALUE, prefix2Index = Integer.MAX_VALUE;
            @Override
            public int compare(String o1, String o2) {
                prefix1Index = Integer.MAX_VALUE;
                prefix2Index = Integer.MAX_VALUE;
                prefix.forEach((pre) -> {
                    if(o1.startsWith(pre)){
                        prefix1Index = prefix.indexOf(pre);
                    }
                    if(o2.startsWith(pre)){
                        prefix2Index = prefix.indexOf(pre);
                    }
                });

                if(prefix1Index == prefix2Index) return o1.compareTo(o2);
                else return prefix1Index - prefix2Index;
            }
        });

        imports.forEach((imported) -> {
            System.out.println(imported);
        });

    }
}

这是输出:

java.util.Arrays
javax.annotation.Generated
org.testng.annotations.Optional
org.testng.annotations.Test
de.bigmichi1.test.ClassB

推荐阅读