Comment puis-je obtenir les n premiers caractères d’une chaîne sans vérifier la taille ou sortir des limites?

Comment puis-je obtenir les n premiers caractères d’une chaîne en Java sans faire d’abord une vérification de la taille (inline est acceptable) ou risquer une IndexOutOfBoundsException ?

Voici une solution soignée:

 Ssortingng upToNCharacters = s.subssortingng(0, Math.min(s.length(), n)); 

Opinion: alors que cette solution est “soignée”, je pense qu’elle est en réalité moins lisible qu’une solution qui utilise if / else de manière évidente. Si le lecteur n’a pas vu cette astuce, il / elle doit penser plus fort pour comprendre le code. IMO, la signification du code est plus évidente dans la version if / else . Pour une solution plus propre / plus lisible, consultez la réponse de @paxdiablo.

Ne réinventez pas la roue …:

 org.apache.commons.lang.SsortingngUtils.subssortingng(Ssortingng s, int start, int len) 

Javadoc dit:

 SsortingngUtils.subssortingng(null, *, *) = null SsortingngUtils.subssortingng("", * , *) = ""; SsortingngUtils.subssortingng("abc", 0, 2) = "ab" SsortingngUtils.subssortingng("abc", 2, 0) = "" SsortingngUtils.subssortingng("abc", 2, 4) = "c" SsortingngUtils.subssortingng("abc", 4, 6) = "" SsortingngUtils.subssortingng("abc", 2, 2) = "" SsortingngUtils.subssortingng("abc", -2, -1) = "b" SsortingngUtils.subssortingng("abc", -4, 2) = "ab" 

Ainsi:

 SsortingngUtils.subssortingng("abc", 0, 4) = "abc" 

Apache Commons Lang a une méthode SsortingngUtils.left pour cela.

 Ssortingng upToNCharacters = SsortingngUtils.left(s, n); 

Il y a une classe de question sur SO qui fait parfois moins que le sens parfait, celle-ci est dangereusement proche 🙂

Vous pourriez peut-être expliquer votre aversion à utiliser l’une des deux méthodes que vous avez exclues.

Si c’est simplement parce que vous ne voulez pas pimenter votre code avec les instructions if ou le code de capture des exceptions, une solution consiste à utiliser une fonction d’assistance qui prendra soin de vous, par exemple:

 static Ssortingng subssortingng_safe (Ssortingng s, int start, int len) { ... } 

qui vérifiera les longueurs à l’avance et agira en conséquence (renvoyer une chaîne plus petite ou un pavé avec des espaces).

Ensuite, vous n’avez pas à vous en soucier dans votre code, appelez simplement:

 Ssortingng s2 = subssortingng_safe (s, 10, 7); 

au lieu de:

 Ssortingng s2 = s.subssortingng (10,7); 

Cela fonctionnerait dans le cas où vous semblez vous inquiéter (en fonction de vos commentaires sur les autres réponses), sans casser le stream du code lorsque vous faites beaucoup de choses pour construire des chaînes.

 Ssortingng upToNCharacters = Ssortingng.format("%."+ n +"s", str); 

Awful si n est une variable (donc vous devez construire la chaîne de format), mais très claire si une constante:

 Ssortingng upToNCharacters = Ssortingng.format("%.10s", str); 

docs

Utilisez la méthode de sous-chaîne, comme suit:

 int n = 8; Ssortingng s = "Hello, World!"; System.out.println(s.subssortingng(0,n); 

Si n est supérieur à la longueur de la chaîne, cela provoquera une exception, comme l’a souligné un commentateur. une solution simple consiste à envelopper tout cela dans la condition if(s.length() dans votre clause else , vous pouvez choisir si vous voulez simplement imprimer / renvoyer la chaîne entière ou la gérer autrement.

ApacheCommons m’a surpris, SsortingngUtils.abbreviate(Ssortingng str, int maxWidth) ajoute “…” il n’y a pas d’option pour changer le postfix. WordUtils.abbreviate(Ssortingng str, int lower, int upper, Ssortingng appendToEnd) recherche le prochain espace vide.

Je vais juste laisser ça ici:

 public static Ssortingng abbreviate(Ssortingng s, int maxLength, Ssortingng appendToEnd) { Ssortingng result = s; appendToEnd = appendToEnd == null ? "" : appendToEnd; if (maxLength >= appendToEnd.length()) { if (s.length()>maxLength) { result = s.subssortingng(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd; } } else { throw new SsortingngIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length."); } return result; }