5 tema. Simbolių eilutės

Turinys
 String klasė
 Simboliai
  Darbo su simboliais metodai
 String klasės metodai
 StringBuffer klasės metodai
 Eilutės rūšiavimas
 Eilutės ir skaičiai
 Skaičių išvedimo formatavimas
 Įvedimas iš failų ir išvedimas į juos
 Užduotys

String klasė

Duomenis programai perduodame kaip simbolių eilutes, programos vykdymo rezultatus irgi dažnai vaizduojame kaip simbolių eilutes. Taigi be simbolių eilučių programuodami neapsieiname nei minutės. Kiekviena simbolių eilutė Java kalbos požiūriu yra objektas . Tiksliau sakysime taip: tai String klasės objektas. Šis teiginys turi maždaug tokią pat prasmę kaip: ,,kiekvienas žmogus yra homo sapiens klasės" objektas. Naujus šios klasės objektus galima apibrėžti, pavyzdžiui, taip:
String s1 ="vardas";
String s2="";
String  s3;
Pirmąją eilutę sudaryta iš 6 simbolių, antroji yra ,,tuščia" eilutė, neturinti nei vieno simbolio, o trečiosios eilutės kol kas yra tik vardas. Ji, galbūt, bus sukurta vėliau. Jeigu eilutė sukurta, tai jos keisti jau nebegalima, t.y. eilutės yra nekintami objektai.

Simboliai

Prieš pradėdami nagrinėti, ką galima veikti su eilutėmis, pakalbėkime apie pačius simbolius. Simboliai Java kalboje yra simbolinio tipo char duomenys. Kiekvienas simbolis atmintyje užima du baitus. Kintamuosius, kurie įgys char tipo reikšmes galime aprašyti taip:
char c1,c2;
Išvardykime visą Java paprasčiausiųjų duomenų tipų sąrašą:
byte, short, int, double, float, double, boolean, char.
Žinome, kad vieno tipo duomenis galima versti kito tipo duomenimis; pavyzdžiui, char tipo duomenis galima versti skaitiniais. Parašykime, įskiepį, demonstruojantį, ką pavertę gauname.

1 pavyzdys. Simboliai ir jų kodai

Programa verčia char tipo duomenis int tipo duomenimis ir vaizduoja duomenų poras teksto lange.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Char extends Applet implements ActionListener{

String st="";
TextArea txt;
Button mygt;
public void init(){
setLayout(new BorderLayout());	
txt = new TextArea();
add("Center",txt);
mygt = new Button("char ir int ");
mygt.addActionListener(this);
add("South",mygt);
}

public void actionPerformed(ActionEvent e)
{for (int i=1; i<256; i++)
{st =st+i+"\t"+ (char) i+"\t";
if (i%5 == 0) {
st=st+"\n ";
txt.append(st); st="";}
}}}


Pažiūrėkite, kaip veikia.    
Atsisiųskite programos tekstą.
Gerai įsižiūrėję į programą turbūt pastebėsime gana keistų, kone nesuprantamų dalykų. Visų pirma, kaip suprasti, kad sukurtos eilutės jau nebegalima pakeisti, jeigu programoje parasyta
 st =st+i+"\t"+ (char) i+"\t"; 
ir Java kompiliatorius viską kuo puikiausiai supranta? Čia įvyksta štai kas: šis užrašas suprantamas kaip reikalavimas sudaryti naują eilutę priduriant prie turimos eilutės nurodytus simbolius, todėl Java sukuria naują eilutę, kuri pavadinama senuoju vardu st. Beje, šioje eilutėje sudėties ženklas jungia net trijų tipų duomenis, taciau Java kuo puikiausiai atlieka darbą! Atkreipkime dėmesį į dėmenis "\t" ir "\n" . Pirmasis tai komanda pereiti į kitą stulpelį (tabuliacijos komanda), antrasis - komanda pereiti į kitą eilutę. Išvardysime keletą darbo su char tipo duomenimis metodų, kurie gali jums praversti.

   Į pradžią   

Darbo su simboliais metodai

char forDigit(int digit, int pgr) Grąžina simbolį, kuriuo užrašomas skaičiavimo sistemos pagrindu pgr skaitmuo digit
boolean isDigit(char ch) Grąžina reikšmę true, jeigu simbolis yra skaitmuo
boolean isLetter(char ch) Grąžina reikšmę true, jeigu simbolis yra raidė
boolean isLetterOrDigit(char ch) Grąžina reikšmę true, jeigu simbolis yra raidė arba skaitmuo
boolean isSpaceChar(char ch) Grąžina reikšmę true, jeigu simbolis tarpas
boolean isLowerCase(char ch) Grąžina reikšmę true, jeigu simbolis yra ,,mažoji raidė"
boolean isUpperCase(char ch) Grąžina reikšmę true, jeigu simbolis yra ,,didžioji raidė"
char toLowerCase(char ch) Grąžina tą patį simbolį, tik ,,mažąją raidę"
boolean toUpperCase(char ch) Grąžina tą patį simbolį, tik ,,didžiąją raidę"


Naudojimosi šiais metodais sintaksė savotiška. Pavyzdžiui, norėdami nustatyti, ar simbolis g yra raidė, turime rašyti Character.isLetter(g); Priešdėlis Character būtinas ir kitiems metodams.

   Į pradžią   

String klasės metodai

O dabar grįžkime prie simbolių eilučių. Jos yra klasės String objektai. Kiekviena klasė turi metodus, kuriuos galima taikyti tos klasės objektams ir gauti tam tikrus rezultatus. Išvardysime, kai kuriuos String klasės public rūšies metodus.

int length() Grąžina eilutės ilgį; pav., jei s="11" tai s.length() reikšmė lygi 2
String toLowerCase()
String toUpperCase()
Sudaro eilutę iš tų pačių simbolių, tačiau užrašytų ,,mažosiomis" (,,didžiosiomis") raidėmis
String trim() Pašalina tarpus eilutės pradžioje ir gale (jei jų yra)
int compareTo(String kitaEilute) Grąžina reikšmę, lygią 0, jei eilutės sutampa; gražina neigiamą reikšmę, jei pirmoji eilutė mažesnė žodyninės tvarkos prasme; jei didesnė - grąžina teigiamą reikšmę
boolean startsWith(String kitaEilute)
boolean endsWith( String kitaEilute)
Grąžina reikšmę true, jei eilutės pradžia (pabaiga) sutampa su kitaEilute
int indexOf(char ch)
int indexOf(String st)
Nurodo numerį pirmos pozicijos, kurioje yra simbolis ch, arba kuria pirmoje eilutėje prasideda fragmentas sutampantis su eilute st
char charAt(int nr) Grąžina simbolį, kurios numeris eilutėje yra nr
char [] toCharArray() Iš eilutės simbolių sudaro char tipo duomenų masyvą

   Į pradžią   

StringBuffer klasės metodai

Ką gi daryti, reikia jeigu reikia pertvarkyti eilutę, ką nors išmesti, įterpti ir t.t. ? Java siūlo tokią išeitį: String objektą pertvarkyti į kitą objektą, kurį jau galima modifikuoti, o po to - atitinkamai modifikavus, vėl sudaryti String objektą. Tie modifikuojami objektai priklauso klasei StringBuffer , o visą eilutės Eil pertvarkymo procesą galima aprašyti taip:
EilMod = new StringBuffer(Eil);  sukuriame StringBuffer klasės objektą Eilmod 
......  atliekame EilMod pertvarkymą 
String EilN = new EilMod.toString();   sudarome naują String objektą iš pertvarkyto EilMod 
Paminėsime keletą StringBuffer klasės metodų.
StringBuffer append(boolean b)
StringBuffer append(char c)
StringBuffer append(int i)
StringBuffer append(float f)
StringBuffer append(double d)
StringBuffer append(String s)
Prie StringBuffer objekto ,,priduria" nurodyto tipo duomenis.
StringBuffer insert(int nr, String Eil)
StringBuffer insert(int nr, char [] smbmas)
StringBuffer insert(int nr, boolean b)
StringBuffer insert(int nr, char c)
StringBuffer insert(int nr, int i)
StringBuffer insert(int nr, long l)
StringBuffer insert(int nr, float fl)
StringBuffer insert(int nr, double d)
Nuo StringBuffer objekto (eilutės) su numeriu nr įterpia eilutę Eil arba eilutėmis paverstus nurodyto tipo duomenis
StringBuffer delete(int start, int end) Pašalina simbolius nuo numerio start iki end
StringBuffer replace(int start, int end, String Eil) Pakeičia simbolius nuo numerio start iki end-1 nurodytos eilutės simboliais
StringBuffer reverse() Buferio simbolius pakeičia tais pačiais, bet perskaitytais nuo galo
String toString() Iš buferio sukuria String objektą, t.y. įprastinę eilutę.

   Į pradžią   

Eilutės rūšiavimas

Kai nurodome, kad duomenys būtų perskaityti iš komandinės eilutės arba teksto lauko, jie perskaitomi kaip viena eilutė. Tačiau toje eilutėje gali būti ir skaičiai, ir tekstinė informaciją, taigi duomenys, kuriuos reikia priskirti keliems kintamiesiems. Ką daryti tokiu atveju? Reikia, kad kompiuteris pasielgtų su įvesta eilute taip, kaip parodyta paveikslėlyje.

Ideologija ta pati, kaip ir su eilučių pertvarkymu. Reikia iš eilutės gauti kitą objektą, kurį jau galima būtų ,,kapoti". Naujųjų objektų klasė vadinasi StringTokenizer Parašysime programėlę, kuri iš eilutės
eil="pirmas antras trečias" 
padarys tris eilutes, kurias priskirs skirtingiems kintamiesiems.
import java.util.*;
public class Skaidymas {
public static main void (String [] args)
{String eil="pirmas antras trečias";
 StringTokenizer st = new StringTokenizer(st);
 String e1 = st.nextToken();
 String e2 = st.nextToken();
 String e3 = st.nextToken();
}
} 
Atkreipkime dėmesį, kad programėlė prasideda eilute import java.util.*; Tai nurodymas, kad reikia importuoti java.util paketą, kur yra mums reikalinga klasė. Programėlėje panaudotas vienas StringTokenizer klasės metodas nextToken(). Jis priskiria dar nepriskirtą eilutės dalį iki sekančio skirtuko. Pagal nutylėjimą skirtukais laikomi tarpai, tabuliacijos ir perėjimo į kitą eilutę simboliai (jie grafiškai nėra vaizduojami). Tačiau galima sukurti StringTokenizer objektą, nurodant kokius simbolius reikia laikyti skirtukais. Pavyzdžiui, šitaip galime nurodyti, kad kableliai, klaustukai ir šauktukai turi būti laikomi skirtukais, taigi ,,kapojant" eilutę tiesiog praleidžiami:
StringTokenizer= new StringTokenizer(eil,",?!");
Išvardykime pagrindinius klasės StringTokenizer metodus.

String nextToken() Grąžina sekantį eilutės fragmentą iki skirtuko; jeigu nebėra ko grąžinti, generuoja ypatingos padėties požymį NoSuchElementException
int countTokens() Skaičiuoja kiek kartų galima be ,,ypatingos padėties įvedimo" pasinaudoti metodu nextToken()
boolean hasMoreTokens() Jeigu eilutė dar netuščia, t.y. dar yra bent vienas skirtukas, perduoda reikšmę true

Eilutės rūšiavimas ir išvedimas

Pasinaudokime išnagrinėtais objektais ir jų savybėmis ir parašykime programą, kuri ,,išrūšiuotų" įvedamą eilutę ir atskirai išvestų žodžius ir skaičius.
import java.util.*;
import java.io.*;
public class Sort{
Sort () {  Čia aprašytas klasės (programos) konstruktorius  
String duom="";
BufferedReader br = new BufferedReader ( 
new InputStreamReader (System.in)); 
System.out.println ("Iveskite duomenis");
try{ duom= br.readLine();}
catch (IOException e) {}
isvesti(duom);
}
         
public  void  isvesti(String s)  Eilutės rūšiavimo ir išvedimo metodas
{String zodziai="", skaiciai="", eil="";
StringTokenizer st= new StringTokenizer(s);
while (st.hasMoreTokens())
{eil=st.nextToken(); 
if (Character.isLetter(eil.charAt(0))) zodziai=zodziai+eil+"\n";
else skaiciai=skaiciai+eil+"\n";
}
System.out.println (zodziai);
System.out.println (skaiciai);
}
public static void main ( String arg[] )  { new Sort();}   pagrindinis  	
} programos metodas; darbu jo neapkrovėme; vienintelė jo pareiga - ,,pažadinti" 
 konstruktorių
Atsisiųskite programos tekstą.

   Į pradžią   

Eilutės ir skaičiai

Skaičius programai perduodame irgi kaip simbolių (skaitmenų) eilutes. Kaip nurodyti programai, kad ji pervestų eilutes į mums reikalingo tipo skaičius? Užrašykime eilutės s pavertimo int, long, float, double tipo skaičiais komandas:
int n = Integer.valueOf(s).intValue();
long l = Long.valueOf(s).longValue();
float f = Float.valueOf(s).floatValue();
double d= Double.valueOf(s).doubleValue();
Nors kai kurias iš šių komandų jau naudojome, jos tikriausiai vistiek atrodo keistokai. Tokį užrašymo stilių diktuoja ,,Java ideologija". Visų pirma, simbolių eilutė yra objektas, taigi ji gali virsti tik objektu, o ne šiaip sau skaičiumi. Pavyzdžiui, komanda Float.valueOf(s) sukuria tokį objektą (klasę.) Tai nėra paprastas float tipo skaičius, galima įsivaizduoti, kad tai tarsi ,,įpakuotas" skaičius. Kad gautume paprastą skaičių, reikia jį ,,išpakuoti". Tai ir atlieka medodas floatValue().

Tiesa, int ir long tipo sveikuosius skaičius iš eilutės galima gauti ir kitaip. Pavyzdžiui, šitaip kintamiesiems n, l priskiriamos iš eilučių gautos reikšmės:
try {
int n = Integer.parseInt(eil1);
long l = Long.parseLong(eil2);
}
catch (NumberFormatException e) { 
 čia gali būti tam tikra informacija, reikalinga
tam atvejui, jei iš eilutės gauti skaičių nepavyktų
 }

   Į pradžią   

Skaičių išvedimo formatavimas

Norėdami, kad mūsų gauti rezultatai (skaičiai ir tekstas) gražiai atrodytų ekrane ar popieriuje, išvedamus duomenis formatuojame. Java suteikia daug įvairių informacijos (teksto, skaičių, datų, užrašytų piniginių sumų) formatavimo galimybių. Panagrinėsime tik skaičių formatavimą.
Skaičiams formatuoti reikia sukurti formatavimo objektą. Galima naudoti kelis skirtingus formatavimo objektus. Šiuos objektus galima suderinti nurodant, kiek skaitmenų turi būti skaičiaus sveikojoje dalyje, kiek po kablelio ir pan. Kaip formatuojami skaičiai geriausia pasimokyti iš pavyzdžio.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.*;
public class Formatav extends Applet implements ActionListener{
String st="";
TextArea txt;
Button mygt;
	  
NumberFormat f1 = NumberFormat.getInstance (); apibrėžiami formatavimą atliekantys
NumberFormat f2 = NumberFormat.getInstance (); objektai 
NumberFormat f3 = NumberFormat.getInstance ();
	  	  
public void init(){
f2.setMinimumIntegerDigits(5); nurodomi formatavimo parametrai  
f2.setMinimumFractionDigits(5);
f3.setMaximumIntegerDigits(5);
f3.setMaximumFractionDigits(5);
	  	
setLayout(new BorderLayout());	
txt = new TextArea();
add("Center",txt);
mygt = new Button("e ir pi ");
mygt.addActionListener(this);
add("South",mygt);
}
	  
public void actionPerformed(ActionEvent e)
{ String s;
double eks=Math.E, pi=Math.PI;
s= "e ir pi \n";
txt.append(s);
s= eks+"  "+ pi+"\n ";  
txt.append(s);
s= f1.format(eks)+"  "+ f1.format(pi)+"\n ";
txt.append(s);
s= f2.format(eks)+"  "+ f2.format(pi)+"\n ";
txt.append(s);
s= f3.format(eks)+"  "+ f3.format(pi)+"\n ";
txt.append(s);
}}
Naudojome tris skaičių formatavimo objektus f1, f2, f3. Pirmajam jokių parametrų nenurodėme, todėl jis naudojo pagal nutylėjimą priskirimus parametrus. Antrajam objektui nurodėme, kiek mažiausiai ženklų turi turėti skaičiaus sveikoji ir trupmeninė dalys; trečiajam parametrui - kiek daugiausia ženklų reikia užrašyti. Atkreipkite dėmesį, kad norint naudoti formatavimą, reikia išsikviesti klasių paketą java.text.
Pažiūrėkite, kaip veikia.    
Atsisiųskite programos tekstą.  

   Į pradžią   

Įvedimas iš failų ir išvedimas į juos

Turbūt jau kiek nusibodo išvedinėti informaciją tik į ekraną ar į teksto lauką įskiepio lange. Programa gali pasiimti duomenis iš failo ir į failą juos užrašyti. Pateiksime programėlės, kuri skaito ir rašo į failą pavyzdį. Tačiau kol kas būtų sunkoka paaiškinti, ką visos jos eilutės reiškia.
 
import java.io.*;
public class Iv_isv{
 Iv_isv () {
 String st;
 FileReader frd;  Skaitymo iš failo ,,įrenginio" vardas 
 FileWriter fwr; Rašymo į  failą ,,įrenginio" vardas 
 try 
{File  fr = new File("iv.txt");
if (! fr.exists())  jeigu failo nėra, jį sukuriame 
{fr.createNewFile();	}
         	
BufferedReader bfrd = new BufferedReader
(frd = new FileReader ("iv.txt"));  skaitymo įrenginio konstravimas 
		
System.out.println ("Pirmoji failo iv.txt eilute");
		
st=bfrd.readLine(); Vienos failo eilutės skaitymas 
System.out.println (st);
frd.close();  ,,išjungiame" skaitymo įrenginį 
System.out.println ("Sukursime faila isv.txt ir isvesime i ji teksta");
        
File  fl = new File("isv.txt");
if (! fl.exists())  { jeigu failo nėra, jį sukuriame 
fl.createNewFile();	}
BufferedWriter bfrw= new BufferedWriter (
new FileWriter("isv.txt"));	 konstruojame rašymo įrenginį  
for (int i= 0; i<10; i++){
bfrw.write("Gyvenimas gražus");
bfrw.newLine();
}
bfrw.close();
}
catch (FileNotFoundException e) {}
catch (IOException e) {}
}
public static void main ( String arg[] ) throws IOException { new Iv_isv();}   	
}
	
Atsisiųskite programos tekstą.

   Į pradžią   

Šiame pavyzdyje buvo perskaityta tik viena failo eilutė. O jeigu eilutė po eilutės turi būti perskaitytos ir atitinkamai apdorotos visos eilutės? Tai galime įvykdyti, pavyzdžiui, sudarę ciklą:
while((st=bfrd.readLine())!==null )
{
... veiksmai su eilute st...
}
Užduotys
  1. Duomenys įvedami iš failo. Reikia juos išrūšiuoti į žodžius ir skaičius. Žodžius ir skaičius išvesti atskirai (į ekraną ar failą). Padaryti taip, kad visi žodžiai prasidėtų didžiosiomis raidėmis. Taip pat apskaičiuoti ir išvesti visų įvestų skaičių sumą.

  2. Duomenys įvedami iš failo. Reikia juos išrūšiuoti į žodžius ir skaičius. Žodžius ir skaičius išvesti atskirai (į ekraną ar failą). Padaryti taip, kad visi žodžiai būtų išvesti perskaičius juos nuo galo į pradžią (iš dešinės į kairę). Surasti didžiausiąjį įvestą skaičių.

  3. Duomenys įvedami iš failo. Reikia juos išrūšiuoti į žodžius ir skaičius. Žodžius ir skaičius išvesti atskirai (į ekraną ar failą). Apskaičiuoti, kiek įvesta žodžių ir kiek skaičių, kiek buvo žodžių prasidedančių a raide (didžiąja ar mažąja).

  4. Duomenys įvedami iš failo. Reikia išrinkti žodžius, prasidedančius didžiąja raide (vardus ar pavardes) ir išvesti tokią informaciją: surastas iš didžiosios raidės prasidedantis žodis ir dar du žodžiai, einantys po jo (jeigu tokių dar yra). Suskaičiuoti, kiek išvesta tokių eilučių.

  5. Duomenys įvedami iš failo. Reikia iš komandinės eilutės įvesti skaičių n ir suskaičiuoti, kiek yra įvesta n ilgio žodžių. Visus šiuos žodžius išvesti į kitą failą, o taip pat ir į ekraną.

  6. Duomenys įvedami iš failo. Reikia iš komandinės eilutės įvesti simbolių eilutę (priešdėlį) ir suskaičiuoti, kiek yra įvesta žodžių prasidedančių šiuo priešdėliu. Visus šiuos žodžius išvesti į kitą failą, o taip pat ir į ekraną.

  7. Duomenys įvedami iš failo. Reikia iš komandinės eilutės įvesti simbolių eilutę (galūnę) ir suskaičiuoti, kiek yra įvesta žodžių besibaigiančių šia galūne. Visus šiuos žodžius išvesti į kitą failą, o taip pat ir į ekraną.

  8. Duomenys įvedami iš failo. Reikia įvesti iš komandinės eilutės kelis simbolius ir apskaičiuoti, kiek kartų tie simboliai pasitaiko failo duomenyse. Rezultatus išvesti į kitą failą, o taip pat ir į ekraną.

  9. Duomenys įvedami iš failo. Įvedus iš komandinės eilutės žodį reikia surasti jį faile ir išvesti į ekraną ir kitą failą kartu su prieš jį įrašytu žodžiu ir po jo užrašytu žodžiu.

  10. Duomenys įvedami iš failo. Reikia surasti ir išvesti į failą ir ekraną visus didžiąja raide prasidedančius žodžius. Apskaičiuoti kiek jų yra iš viso.