|
Ja portes força pràctiques
en què fas anar cadenes de caràcters de text, paraules,
tipificades com a objectes de la classe String.
Les classes java.lang.String i java.lang.StringBuffer,
amb els seus mètodes, són les eines fonamentals que ofereix
el SDK
de Java per a la manipulació
dels elements de text. Ara toca un estudi més extens d'això.
Ens restringim, però, a la classe String
i no direm res més de la classe StringBuffer. |
|
|
|
|
|
Una cadena ("string"
en anglès, en el sentit de "enfilall", "reguitzell":
sèrie de coses que vénen una darrera l'altra sense interrupció)
és això: una tirallonga de caràcters de text posats
en un cert ordre. Els objectes de la classe java.lang.String
representen cadenes. |
|
|
|
|
|
La manera més senzilla de
construir una cadena és aquesta: |
|
|
|
|
|
String
unaCadena="La Tia Maria";
String unaAltraCadena="Setze jutges mengen fetge d'un penjat";
String encaraUnaAltraCadena="569%$7)!!!-pw¿àH>*Ç}"; |
|
|
|
|
|
|
Es tracta, doncs, de delimitar els caràcters que componen la cadena
per una parella de cometes dobles "".
|
|
|
|
|
 |
Una primera cosa que se't pot ocórrer
és: com s'ha de fer per tal que unes cometes,""",
siguin de la cadena? El compilador no les interpretarà com a "final
de cadena" i se'n perdrà la continuació? |
|
|
|
|
|
Sí, sí, és
clar que sí! Això introdueix el tema dels caràcters
d'escapament: aquests són caràcters precedits d'una
contrabarra, "\", que, d'una banda,
tenen una funció especial i, de l'altra, permeten que els caràcters
amb significat especial puguin ser inclosos en cadenes, perdent així
aquest significat especial. Els més corrents són aquests: |
|
|
|
|
|
|
Nom |
Ús |
\n |
Canvi de línia |
Per passar a la línia següent |
\t |
Tabulador (8 espais) |
Per tabular |
\" |
Cometes |
Per poder posar """
com a component d'una cadena |
\\ |
Contrabarra |
Per poder posar "\"
com a component d'una cadena |
|
|
|
|
|
|
Vegem com funcionen. Obre un nou
projecte que es digui Cadenes i afegeix-li aquesta
classe: |
|
|
|
|
 |
/**
* La classe CaractersEscapament té un únic mètode
que serveix per
* comprovar la funció dels caràcters d'escapament \n,
\t, \" i \\.
*
* @author Carles Romero
* @version 2003/02/29
*/
public final class CaractersEscapament {
/**
* Mètode que serveix per comprovar
la funció dels caràcters
* d'escapament \n, \t, \" i \\
i la funció de l'operador +
* per enganxar cadenes una a continuació
d'una altra.
*/
public
static void metodeDeMostra () {
String
ambCanviDeLinia=
"Aquesta
és la primera línia\ni "+
"aquesta
és la segona";
String
ambTabuladors=
"Dada
1\tDada 2\t\tDada 4\nDada 5\t"+
"Dada
6\tDada 7\tDada 8";
String
ambCometesIContrabarres=
"El
caràcter \\ es diu "+
"una
\"contrabarra\"";
System.out.println
("====================================");
System.out.println("Canvis
de línia:");
System.out.println(ambCanviDeLinia);
System.out.println
("====================================");
System.out.println("Tabuladors:");
System.out.println(ambTabuladors);
System.out.println
("====================================");
System.out.println("Cometes
i contrabarres:");
System.out.println(ambCometesIContrabarres);
System.out.println
("====================================");
}
}
|
|
|
|
|
|
|
Compila i, com que l'únic
mètode que té la classe és static,
no cal crear-ne cap objecte. El pots cridar directament: |
|
|
|
|
|
|
|
|
|
|
|
i veure'n els resultats. Naturalment,
et suggerim que facis canvis a les cadenes ambCanviDeLinia,
ambTabuladors i ambCometesIContrabarres
i, també, que en creis de noves. |
|
|
|
|
|
Els mètodes de la classe
java.lang.String: |
|
|
|
|
|
La classe java.lang.String conté els
mètodes necessaris per a...
- determinar la longitud (nombre de caràcters) d'una
cadena
- examinar individualment els caràcters que conté
- comparar cadenes lexicogràficament
- buscar i extreure subcadenes d'una cadena
- transformar tots els seus caràcters a majúscules o
a minúscules
- ...i d'altres mètodes per executar procediments ben diversos.
A més, com ja has vist en l'exemple anterior, es pot fer servir
l'operador "+" per a enganxar dues
cadenes i formar-ne una de sola.
Tot seguit tens uns quants exemples de la sintaxi adequada:
|
|
|
|
|
|
- public int length(). Retorna la longitud
de la cadena, és a dir, el nombre de caràcters que conté.
Així:
String
cadena="Això és una cadena";
int n=cadena.length(); |
posa un 18 a la variable n.
|
|
|
|
|
|
- public String substring(int
inici). Extreu una subcadena que té com a primer
caràcter el que ocupava el lloc inici
a la cadena original i , com a darrer, el darrer de la cadena. Així,
a
String
cadena="Això és una cadena";
String subcadenaU=cadena.substring(2);
String subcadenaDos=cadena.substring(5); |
resulta subcadenaU="xò és una
cadena " i subcadenaDos="és
una cadena".
Fes atenció a que...
- inici no superi
la longitud de la cadena, perquè et trobaries amb una excepció
del tipus StringIndexOutOfBoundsException
que t'aturaria el programa!
- La primera posició correspon al 0,
la segona a l'1, etc. Per aquesta raó
cadena.substring(2) comença a la
x de "Això...
|
|
|
|
|
|
- public String substring(int
inici,int final). Extreu una subcadena que té com
a primer caràcter el que ocupava el lloc inici
a la cadena original i , com a darrer, el que ocupava el lloc final-1
a la inicial. Així, a
String
cadena="Això és una cadena";
String subcadenaU=cadena.substring(2,9);
String subcadenaDos=cadena.substring(5,6);
String subcadenaTres=cadena.substring(4,5);
String subcadenaQuatre=cadena.substring(1,1); |
resulta subcadenaU="xò és u",
subcadenaDos="é", subcadenaTres="
" i subcadenaQuatre="".
Novament, vigila que ni inici ni final
superin la longitud de la cadena, perquèm, com en el cas anterior,
et trobaries amb una excepció StringIndexOutOfBoundsException!
|
|
|
|
|
|
- public String toUpperCase() i public
String toLowerCase() retornen, respectivament, cadenes que resulten
del pas a majúscula i a minúscula dels caràcters
de la cadena original:
String cadena="Títol: El Rector de Vallfogona";
String cadena_A=cadena.toUpperCase();
String cadena_A=cadena.toLowerCase();
|
El resultats són: cadena_A="TÍTOL:
EL RECTOR DE VALLFOGONA" i cadena_B="títol:
el rector de vallfogona".
|
|
|
|
|
|
- public boolean equals(Object unObjecte).
Retorna true si, i només si, l'objecte
unObjecte és una instància de
la classe String que representa exactament
la mateixa successió de caràcters. Exemple:
String cadena="Balsareny";
String cadena_A="Gironella";
String cadena_B="BalSareny";
String cadena_C="Balsareny";
boolean laA=cadena.equals(cadena_A);
boolean laB=cadena.equals(cadena_B);
boolean laC=cadena.equals(cadena_C);
|
Resulta: laA=false, laB=false
i laC=true.
És totalment aconsellable fer servir la formulació anterior
per definir els booleans i, en canvi, és completament desaconsellable
plantejar-ho amb la sintaxi següent:
boolean laA=(cadena==cadena_A);
boolean laB=(cadena==cadena_B);
boolean laC=(cadena==cadena_C);
|
perquè, malgrat que dues cadenes continguin exactament
els mateixos caràcters, són objectes diferents,
és a dir, a la memòria, resideixen en llocs diferents
i tenen, probablement, identificadors, també diferents. Ens podem
trobar (depèn del sistema i de la manera com hagin estat construïdes
les cadenes) que Java
ens digui que "Tres quarts de quinze"=="Tres
quarts de quinze" és false!
|
|
|
|
|
|
|
|
|
|
|
|
- public int compareTo(String
unaCadena). Fa la comparació lexicogràfica de la
cadena propietària del mètode (l'ordre d'un diccionari)
amb la cadena unaCadena. El resultat és
un nombre negatiu si unaCadena li és
posterior, i positiu si unaCadena li és
anterior. Si les dues cadenes són iguals, aleshores retorna un
zero:
String cadena="Balsareny";
String cadena_A="Gironella";
String cadena_B="Avià";
String cadena_C="Balsareny";
int laA=cadena.compareTo(cadena_A);
int laB=cadena.compareTo(cadena_B);
int laC=cadena.compareTo(cadena_C);
|
Resulta: laA=<nombre negatiu>,
laB=<nombre positiu> i laC=0.
|
|
|
|
|
|
Pots trobar més mètodes i les explicacions a la documentació
de la classe java.lang.String.
A la pràctica 2
del mòdul 4 t'expliquem idees generals sobre la documentació
dels projectes de Java i com la podràs
confegir per als teus projectes. Ara bé, les classes públiques
elaborades pels programadors de Sun
Microsystems, com és ara la java.lang.String,
tenen documentacions excel·lents que ens faciliten tots els detalls
que ens permetran importar-les i aprofitar-les per als nostres projectes.
Pots veure-ho si enllaces amb la pàgina web "oficial"
de Java;
per a la classe String, la documentació
es troba a
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html
per a la darrera versió oficial del programa quan s'han redactat
aquests materials, a saber, J2SE
1.4.2 SDK. Allà trobaràs molts més mètodes
i més explicacions.
|
|
|
|
|
|
De nombres a cadenes: |
|
|
|
|
|
Sovint convé representar
valors numèrics (enters, reals) com a cadenes: moltes
vegades necessitaràs que el nombre int n=51
es representi per la cadena de caràcters de text "51".
La classe java.lang.String, tot fent una bona
exemplificació de sobrecàrrega, (donar el mateix nom
a mètodes diferents, en l'argot dels programadors, es diu "sobrecàrrega
de mètodes". La màquina els distingeix, no pel nom,
que és el mateix, sinó pels paràmetres, que han de
ser, obligatòriament diferents!) té aquests mètodes
static, que fan precisament això: |
|
|
|
|
|
- public static String
valueOf(boolean b). Retorna la representació com a cadena
del valor de veritat de la variable boolean b:
boolean
b_1=(2==3);
boolean b_2=(3==3);
String cadenaB_1=String.valueOf(b_1);
String cadenaB_2=String.valueOf(b_2); |
Aleshores, b_1=false, b_2=true,
cadenaB1="false" i cadenaB_2="true".
Observa que, com que el mètode és static,
cal cridar-lo tot posant com a prefix el nom de la classe, "String",
no pas el de cap objecte de la classe String.
(Mira la corresponent explicació a la pràctica
5 del mòdul 2)
|
|
|
|
|
|
- public static String
valueOf(int n). Retorna la representació com a cadena
del valor numèric de la variable int n:
int
n_1=-436;
int n_2=2004;
String cadenaN_1=String.valueOf(n_1);
String cadenaN_2=String.valueOf(n_2); |
Resulta n_1=-436, n_2=2004
i cadenaN_1="-436", cadenaN_2="2004".
Observa que n_1+n_2=1568, però cadenaN_1+cadenaN_2="-4362004".
Igualment, n_1-n_2=-2440, però cadenaN_1-cadenaN_2
no té sentit.
Observa, a més, que aquest mètode té el mateix
nom que l'anterior: valueOf, però el
paràmetre és ara int n, en lloc
de boolean b. Això és, precisament,
la sobrecàrrega de mètodes.
|
|
|
|
|
|
- public static String
valueOf(double db), public static String valueOf(float
fl)i public static String valueOf(long lng)
fan la mateixa feina, però per a valors numèrics dels
tipus double, float
i long respectivament. (Més sobrecàrrega!)
|
|
|
|
|
|
Les conversions inverses (de String a int,
de String a float,
etc.) no són, com és lògic, mètodes de la
classe String, sinó que són mètodes
static de les corresponents classes Integer,
Float, etc:
- static int Integer.parseInt(String string)
- static float Float.parseFloat(String string)
- static double Double.parseDouble(String
string).
|
|
|
|
|
|
Posem a funcionar tot això: |
|
|
|
|
|
Ara escriuràs una classe que serà capaç de detectar
els nombres de quadrat automòrfic (uix!) que hi ha entre
zero i un cert valor màxim.
Es diu que un nombre és de quadrat automòrfic
si coincideix amb les darreres xifres del seu quadrat.
-
25
és de quadrat automòrfic, perquè les dues darreres
xifres del seu quadrat, que és 625
configuren, precisament, la cadena "25".
-
376
també ho és perquè 3762
= 141376.
- En canvi 45 no ho és perquè
452 = 2025. La cadena de les
dues darreres xifres del quadrat és "25",
diferent de la "45" inicial.
|
|
|
|
|
 |
Al projecte Cadenes
afegeix-li la classe NombresAutomorfics amb aquest
codi: |
|
|
|
|
|
/**
* Per a cercar els nombres de quadrat automòrfic, és
a
* dir, els nombres que coincideixen amb les darreres
* xifres del seu quadrat.
*
* @author Santiago Manrique
* @version 2004/01/26
*/
public class NombresAutomorfics {
/**
* El màxim dels nombres que
es comprovaran.
*/
private
int maxim;
/**
* Mètode constructor per a
objectes de la classe
* NombresAutomorfics.
* @param elMaxim el màxim dels
nombres que es comprovaran
*/
public
NombresAutomorfics (int elMaxim) { //
constructor
maxim=elMaxim;
}
/**
* Imprimeix una llista els nombres
de quadrat automòrfic
* menors que el maxim indicat.
*/
public
void llistarAutomorfic () {
System.out.println("\tNombre:\tQuadrat:");
for
(int i=0; i<=maxim;i++) {
String
valor=String.valueOf(i);
String
quadrat=String.valueOf(i*i);
int
longValor=valor.length();
int
longQuadrat=quadrat.length();
String
perComparar= quadrat.substring(longQuadrat-longValor);
if
(valor.equals(perComparar)) {
System.out.println("\t"+valor+
"\t"+quadrat);
}
}
}
}
|
|
|
|
|
|
|
Anàlitzem ara
el codi: |
|
|
|
|
|
- Es comença per declarar la variable
d'instància int maxim:
que contindrà el nombre màxim que la classe comprovarà
per veure si és de quadrat automòrfic o no.
|
|
|
|
|
|
Després vé
el mètode constructor:
public
NombresAutomorfics (int elMaxim) {
//constructor
maxim=elMaxim;
} |
que es limita a dipositar el valor int elMaxim,
que rep com a paràmetre, a la variable d'instància int
maxim.
Per què s'ha de fer això? Perquè ara, aquest valor
ja està a la disposició de qualsevol altre mètode de
la classe. |
|
|
|
|
|
- Finalment, hi ha el mètode public
void llistarAutomorfic (), el qual analitza els nombres de 0
a elMaxim, i imprimeix els que siguin de de
quadrat automòrfic.
- A la primera línia d'aquest mètode s'imprimeix una
capçalera per a la taula de nombres de quadrat automòrfics
que imprimirà després. Observa l'ús del caràcter
de tabulació "\t":
System.out.println("\tNombre:\tQuadrat:"); |
- Aleshores comença una estructura for(...)
{...} per fer l'anàlisi de tots i cadascun dels nombres
de 0 a elMaxim.
La primera acció és convertir aquests nombres i els
seus quadrats a cadenes de caràcters:
String
valor=String.valueOf(i);
String
quadrat=String.valueOf(i*i); |
- Després se'n demana la longitud, és a dir el nombre
de caràcters (xifres, en aquest cas) de cadascuna de les
dues cadenes:
int
longValor=valor.length();
int
longQuadrat=quadrat.length(); |
- Ara cal mirar les últimes xifres de la cadena quadrat
per poder-les comparar amb la cadena valor
completa. Es tracta d'extreure'n la subcadena que comença
just a la posició longQuadrat-longValor:
StringperComparar=
quadrat.substring(longQuadrat-longValor); |
|
|
|
|
|
|
- Ja està tot a punt. Es tracta de mirar si la cadena valor
i la cadena perComparar són iguals:
if
(valor.equals(perComparar)) { |
Si ho són, que vol dir que i (la
variable comptador del bucle, que s'ha transformat a cadena valor
pel mètode
String.valueOf(i))
és de quadrat automòrfic, imprimeix les cadenes amb les
xifres del nombre i les del seu quadrat:
System.out.println("\t"+valor+
"\t"+quadrat); |
amb els corresponents caràcters "\t"
de tabulació, per tal d'aconseguir una taula clara i fàcilment
legible.
|
|
|
|
|
|
Ara ja pots compilar
i comprovar que tot funciona bé. Crea un objecte d'aquesta classe,
amb 10000 com a paràmetre del mètode
constructor, l'inspecciones per comprovar que el camp int
maxim conté, efectivament, 10000,
i després executa el mètode public void
llistarAutomorfic (): |
|
|
|
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
Voilà! |
|
|
|
 |