Search code examples
javasortingjava-8java-streamcollect

Private Sorting Rule in a Stream Java


Hey if anyone has an idea I would be really thankfull. I'm in a Java stream and i would like to sort my list that i'll be returning. I need to sort the list via TradPrefis ( MyObject::getTradPrefix ). But this would be way too easy. Because i want to sort following the number at the end of TradPrefix exampleTradPrefix_[NUMBER TO SORT]

Exemple : hello_1 test_2 ... still_there_22

Here is a piece of code so you can imagine easier.

public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
    LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
    return (toReturn.stream()
            .map(this::createWsQuestion)
            .sorted(comparing(WsQuestion::getTradPrefix.toString().length()))
            .collect(Collectors.toCollection(LinkedHashSet::new)));
}

Solution

  • If I where you I would simply put a method on the WsQuestion class, let's call it sort order:

    public int getSortOrder() {
      return Integer.valueOf(tradPrefix.substring(tradPrefix.lastIndexOf("_") + 1));
    }
    

    The Integer parse is needed since comparing strings would give "11" < "2" (thanks Holger for pointing this out). The lastIndexOf() makes sure that any number of underscores are allowed in tradPrefix, as long as there is at least one.

    Then simply create a comparotor by using Comparator.comparingInt()

    public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
      LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
      return (toReturn.stream()
          .map(this::createWsQuestion)
          .sorted(comparingInt(WsQuestion::getSortOrder))
          .collect(Collectors.toCollection(LinkedHashSet::new)));
    }