简体   繁体   English

根据另一个字符串数组定义的顺序对字符串 ArrayList 进行排序

[英]Sort a String ArrayList based on order defined by another String Array

I've seen several other questions similar to this one but I haven't really been able to find anything that resolves my problem.我已经看到了与此类似的其他几个问题,但我还没有真正找到任何可以解决我的问题的问题。

What would be the way to sort numberWords ArrayList based on ORDER array?基于ORDER数组对numberWords ArrayList 进行排序的方法是什么?

I'm not saying that numberWords must be ArrayList , it can be an array as well, but I thought it might fit better for getStoredWords() method as I should return List<String> .我并不是说numberWords必须是ArrayList ,它也可以是一个array ,但我认为它可能更适合getStoredWords()方法,因为我应该返回List<String> Tried to compare numberWords to ORDER eg numberWords.get(first).equals(ORDER[first]) , but it didn't work out the way it should.试图将numberWordsORDER进行比较,例如numberWords.get(first).equals(ORDER[first]) ,但它并没有达到应有的效果。

public class WordStore {
    List<String> numberWords = new ArrayList<>();

    private static final String[] ORDER = {
            "one", "two", "three", "four", "five",
            "six", "seven", "eight", "nine", "ten"
    };

    public void add(String numberAsWord) {
        numberWords.add(numberAsWord);
    }

    public List<String> getStoredWords() {
        
    }
}

Example tests:示例测试:

public void insertedInArbitraryOrder() {
        WordStore wordStore = new WordStore();

        wordStore.add("three");
        wordStore.add("one");
        wordStore.add("two");
        wordStore.add("ten");
        wordStore.add("one");
        wordStore.add("five");
        wordStore.add("ten");
        wordStore.add("nine");
        wordStore.add("eight");

        assertThat(wordStore.getStoredWords(),
                contains("one", "one", "two", "three",
                        "five", "eight", "nine", "ten", "ten"));
    }
public void insertedInReverseOrder() {
        WordStore wordStore = new WordStore();

        wordStore.add("three");
        wordStore.add("two");
        wordStore.add("one");

        assertThat(wordStore.getStoredWords(),
                contains("one", "two", "three"));

    }

It can be a one-liner, but don't do it , this approach is not good performance-wise.它可以是单线的,但不要这样做,这种方法在性能方面不好。

numberWords.sort(Comparator.comparingInt(ORDER::indexOf));               // DON'T use me

However, let's reuse the idea of the look-up based on the index of each word as the order definition.但是,让我们重用基于每个单词的索引进行查找的思想作为顺序定义。

You need two steps:你需要两个步骤:

  1. Extraction : Assign a numeric order to each word in ORDERS .提取:为ORDERS中的每个单词分配一个数字顺序。 The data structure Map<String, Integer> is suitable for it.数据结构Map<String, Integer>适合它。 The HashMap is useful for look-up based on the word. HashMap对于基于单词的查找很有用。

     Map<String, Integer> orders = IntStream.range(0, ORDER.length).boxed().collect(Collectors.toMap(i -> ORDER[i], Function.identity()));

    The key is the word itself (for look-up) and value is its position or index.关键是单词本身(用于查找),值是它的 position 或索引。

  2. Sort : Using the comparison based on the integers obtained through the map for each word.排序:使用基于通过 map 获得的整数对每个单词进行比较。

     numberWords.sort(Comparator.comparingInt(orders::get));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM