2
votes

Un moyen simple d'analyser les nombres sous forme de chaînes lors du tri avec des flux Java?

J'ai une liste d'objets qui contiennent des valeurs stockées sous forme de chaînes mais qui sont en fait des nombres et j'essaie de trouver un moyen d'analyser des chaînes en entiers dans un flux Java pour les trier numériquement. Voici ce que j'ai obtenu jusqu'à présent.

3356001017053000000000000
3356001017002000000000000
3356001017004000000000000
3356001017026000000000000
5101004003020000000000000
4123000006002510000000000
4758000005010000000000000

Pour le moment, ce genre de travail fonctionne, mais le problème est que parce que ces nombres sont en fait des chaînes, il trie les nombres lexicographiquement, pas numériquement. Existe-t-il un moyen d'incorporer l'analyse dans le flux? Tous les nombres sont remplis pour avoir la même taille.

List<SearchResultObject> returnedValues = doTheSearchMethod();
returnedValues = returnedValues
.stream()
.sorted(Comparator.comparing(SearchResultObject::getNumber))
.collect(Collectors.toList());


1 commentaires

Qu'en est-il du changement de Search Result Object.get Number () pour qu'il renvoie une instance long ou Number ?


4 Réponses :


1
votes

utilisez compareLong puis analysez long. les nombres sont trop grands pour les entiers.

returnedValues.sort(Comparator.comparingLong(sro->Long.parseLong(sro.getNumber())));


0 commentaires

0
votes

Pour simplement trier, vous n'avez pas besoin de flux, utilisez simplement un Comparator personnalisé en utilisant l'expression lambda

Collections.sort(returnedValues,c);

Et puis utilisez Collections.sort code > méthode

Comparator<SearchResultObject> c = Comparator.comparingLong(s->Long.parseLong(s.getNumber()));


0 commentaires

0
votes

Vous n'avez pas besoin d'utiliser l'API Streams pour trier la liste, vous pouvez utiliser directement la méthode sort () depuis l'interface de liste. Vous devez juste vous assurer que vous fournissez un comparateur approprié à la méthode sort () .

Comme vous l'avez mentionné, vous pouvez utiliser directement:

Before sorting
SearchResultObject{number='100'}
SearchResultObject{number='2'}
SearchResultObject{number='10'}
After sorting
SearchResultObject{number='2'}
SearchResultObject{number='10'}
SearchResultObject{number='100'}

comparateur pour comparer les chaînes.

Cependant, comme vous avez besoin que la liste soit triée en comparant Entier / Long, vous pouvez utiliser ce qui suit:

  1. Pour un entier:

    list.sort (Comparator.comparingInt (s -> Integer.parseInt (s.getNumber ())));

  2. Pour longtemps:

    list.sort (Comparator.comparingLong (s -> Long.parseLong (s.getNumber ())));

Vous pouvez vérifier la sortie pour le code suivant ci-dessous:

Comparator.comparing(SearchResultObject::getNumber)

La sortie ci-dessus est basée sur l'hypothèse de SearchResultObject contient un numéro comme champ.


0 commentaires

0
votes

Si vous pouvez modifier SearchResultObject , ajoutez-y une méthode en convertissant la String en BigInteger et utilisez-la dans votre Comparator code>

returnedValues.stream()
              .sorted(
                  Comparator.comparing(
                      sro -> new BigInteger(sro.getNumber())
                  )
              )
              .collect(toList());

Et l'appel est

returnedValues.stream()
              .sorted(
                  Comparator.comparing(
                      SearchResultObject::getNumberAsBigInteger
                  )
              )
              .collect(Collectors.toList());

Si vous ne pouvez pas modifier le SearchResultObject classe, alors vous devrez personnaliser un peu votre Comparateur , mais rien de trop compliqué

public SearchResultObject {
    ...
    public BigInteger getNumberAsBigInteger() {
        return new BigInteger(this.number);
    }
    ...
}


0 commentaires