根据给定的前缀对字符串列表进行排序

时间:2019-09-08 08:07:22

标签: java

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

已经尝试了基于来自另一个线程How to sort a java list against a custom order的解决方案的自定义比较器。但是我现在被困在要求的最后一部分,以便将列表末尾没有前缀的其余条目带入。

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

1 个答案:

答案 0 :(得分:2)

这是我要怎么做:

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