1
Inmatning och utskrift
Inmatning från tangentbord och utskrift till skärm sker i java med hjälp av objekten System.out och
System.in. Dessa båda objekt är exempel på strömmar. En ström är en typ som kan läsa och skriva
data mellan en sändare och en mottagare. Objekten in och out är medlemmar i klassen System.
Finessen med strömmar är att vi får ett konsekvent sätt att läsa och skriva data oavsett källan(i deta fall
konsollfönstret). in läser text i form av en InputStream, out skriver text som en PrintStream. se
http://w3.miun.se/javadocs/java/io/InputStream.html och
http://w3.miun.se/javadocs/java/io/PrintStream.html.
Vi har tidigare sett exempel på utskrift. Vi kommer i det här avsnittet även ta upp inmatning från
tangentbordet så att vi kan skapa program som kommunicerar med en användare istället för att
använda värden inskrivna i programkoden.
1.1
Utskrift till skärm
För att skriva data till skärmen ( konsolen) används objektet System.out tillsammans med metoden
println eller print.
System.out.println("Hello");
1.1.1
Typen String
Metoden println tar ett argument av typen String, texttypen (Den kan även ta enstaka värden av andra
typer och omvandla dessa till string). Då man slår ihop, konkatenerar, strängar med andra typer måste
man vara försiktig
System.out.println( 3 + 6 + "Hello");
Vad ska skrivas ut, "36Hello" eller "9Hello" ?
Det som skrivs ut är "9Hello" eftersom man utvärderar det sammansatta uttrycket från vänster till
höger.
Uttrycket (int)+(String) omvandlas automatiskt till ett String resultat. Detsamma gäller för andra
taltyper.
System.out.println("Hello" + 3 + 6);
Vad blir resultatet av detta? Testa genom att foga in satsen i main.. {
Blev det det du förväntade dig?
1.2
Inmatning från tangentbordet
Inmatning görs med objektet System.in. Objektet är till för att läsa textrader. Eftersom man ofta vill
läsa in andra värden än just hela rader av text finns en hjälpklass döpt Scanner för att underlätta
inmatning av heltal, flyttal osv.
För att ta emot inmatning av ett heltal från tangentbordet kan man skriva:
Scanner tgb = new Scanner( System.in );
Detta är första gången då vi haft en anleding att skapa ett objekt. Uttrycket new Scanner( System.in );
innbär att vi skapar ett objekt, eller en instans, av typen Scanner. Scanner är en klass som beskriver
metoder att läsa värden från en ström eller annan datakälla. Datakällan vi angivit är System.in som
representerar tangentbordet.
Terminologi: Konstruerare. new Scanner beskriver en konstruktion av en Scanner-instans, vi anropar
en konstruerare hos Scanner.
Exempel:
import java.util.*;
class KeyboardReading
{
public static void main(String [] arg)
{
Scanner tgb = new Scanner(System.in);
System.out.println("Hur många endollarmynt har du?");
int antalDollar;
antalDollar = tgb.nextInt();
System.out.println("Jaså du har "+ antalDollar + " stycken.");
}
}
Glömmer man att lägga till ledtext till inmatningen, eller kanske rentav råkar lägga den efter
inmatningen, kommer programmet att vänta på en inmatning från användaren, och användaren
kommer i sin tur att inte ha en aning om att programmet väntar tålmodigt på en inmatning.
1.2.1
Klasser och objekt
Vi utnyttjar klassen Scanner för att skapa objektet tgb. Vi utnyttjar sedan objektet med hjälp av
medlemsväljaren . (punkt).
Ett objekt har metoder och attribut dessa båda kallas sammantaget för objektets medlemmar.
Tumregeln är att man använder metoder för att använda objektet. Metoderna använder (det ser vi inte)
i sin tur attributen för att utföra sin uppgift. Man kan här tänka sig hur Scanner utnyttjar System.in för
att läsa från tangentbordet.
Det som sker bakom kulisserna är:
tgb.nextInt() => läs siffertecken från System.in tills man stöter på ett mellanslag. Omvandla detta till
typen int. Ge tillbaka int-värdet.
Om vi vänder blicken mot den nu välbekanta satsen System.out.println ser vi att det finns två
medlemsväljare. Vi kan läsa ut det som att out är en medlem av System (ett attribut), och println är en
medlem av out (en metod).
Programmet ovan kan ge resultatet
Hur många endollarmynt har du?
7
Jaså du har 7 stycken
1.2.2
Paket
Den första satsen i föregående exempel är
import java.util.*;
Alla klasser i javabiblioteket är uppdelade i paket, för att man enklare ska hitta dom. Om man vill
använda någon annan klass än de mest basala, såsom System och String, måste man importera det
paket som innehåller klassen ifråga. Scannerklassen ligger i ett paket som heter java.util och satsen
import java.util.*; innebär läs in alla klasser ifrån paketet java.util. * är ett sk wildcard, och anger
alltså alla klasser i paketet. Alternativt kan vi skriva
import java.util.Scanner;
för att bara importera just Scanner-klassen. Vilket skrivsätt vi väljer är för närvarande en smaksak. Vid
större projekt och nätbaserade applikationer kan skrivsättet komma påverka applikationen, men för
vårt vidkommande är det en smaksak.
1.2.3
Exempelprogram
Beräkna area och omkrets hos en rektangel.
En viktig komponent att skapa ett eget program utfrån en beskrivning är att först tänka sig, göra en
modell, hur programmet bör fungera. Man kan till exempel tänka sig att programmet fungerar som
Ange bredd: 4
Ange höjd: 2,5
Arean är 10.0, omkretsen är 13.0
Nu kan man se i vilken ordning man vill sätta ihop programsatserna
import java.util.*;
class KeyboardReading
{
public static void main(String [] arg)
{
double bredd, höjd;
Scanner tgb = new Scanner(System.in);
System.out.println("Ange bredd?");
bredd = tgb.nextDouble();
System.out.println("Ange höjd?");
höjd = tgb.nextDouble();
double omkrets = 2*bredd + 2*höjd;
double area = bredd* höjd;
System.out.println("Arean är "+area+", omkretsen är "+omkrets);
}
}
1.2.4
Övning:
Skriv ett program som frågar efter hur gammal du är, och därefter berättar hur många dagar du levat.
Dela upp lösningen i olika steg.
Börja med att fundera på hur du vill att beräkningen ska gå till. Då du vet hur du vill att beräkningen
ska fungera tänker du ut hur användardialogen (programkörningen med in och utmatningar) ska se ut.
Därefter kan du börja skriva programmet genom att titta på tidigare exempel. Tänk särskilt på vilka
variabler du behöver och vilka datatyper dessa variabler bör ha.
2
Mer om operatorer
2.1
Utvärderingsregler
Betrakta satsen
omkrets = 2*bredd + 2*höjd;
Om bredden är 4 och höjden är 2.5 så vill vi att uträkningen ska utföras som
1: 2*4 =8
2: 2*2.5 =5
Därefter
3: (1:+2: ) 8 + 5 = 13
Därefter
4: omkrets = 13
För att åstakomma detta finns 2 parametrar som bestämmer i vilken ordning operatorerna utvärderas
1- Operatorprioritet
2- Utvärderingsriktning
Operatorn * har högst prioritet av de inblandade operatorerna och utvärderas därför först, 1: och 2:.
Därefter kommer + i prioritetsordning, 3: . Sist kommer =, tilldelningsoperatorn 4: .
Utvärderingsriktning är från vänster till höger, alltså den riktning man normalt läser, för alla operatorer
utom tilldelningsoperatorerna, som utvärderas från höger till vänster.
Utvärderingsriktningen ger att 1: utförs före 2:
Att tilldelningsoperatorn har utvärderingsriktning höger till vänster gör att man kan göra sammansatta
tilldelningar såsom
int i, j;
i = j = 5;
1: j = 5, resultatet av denna operation är j, dvs heltalet 5
2: i = j eller om man så vill i = 5
2.2
Exempel
Sammansatta satser behöver man lite träning för att tolka på ett riktigt sätt; också naturligtvis för att
kunna skriva dem själv. Om en beräkning blir för komplex, delar man gärna upp den på flera mindre
delar.
double omkrets = 2*bredd + 2*höjd;
// kan skrivas om som
double omkrets = 2*( bredd + höjd );
// radien av en cirkel
int diameter = 3;
double radie = (double)diameter / 2; // (double) omvandlar typ på diameter
double area = radie*radie* 3.14; // x upphöjt i 2 skrivs som x*x
// ytan på en hel cylinder
double radie = 2.0;
double höjd = 4.0;
double cylinderYta = 2*radie*radie*3.14159
+ höjd*radie*2*3.14159;
// En så pass komplex sats delar man gärna upp
double radie = 2.0;
double höjd = 4.0;
double sidYta = höjd* radie*2*3.14159;
double toppYta = radie*radie*3.14159;
double cylinderYta = sidYta + 2*toppYta;
Operator Precedence
postfix operators
expr++ expr--
unary operators
++expr --expr +expr -expr ~ !
multiplicative
* / %
additive
+ -
shift
<< >> >>>
relational
< > <= >= instanceof
equality
== !=
bitwise AND
&
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND
&&
logical OR
||
conditional
? :
assignment
= += -= *= /= %= &= ^= |= <<= >>= >>>=
Källa: java.sun.com
3
Alternativ till konsollinmatning
Det finns mycket hjälp att få i javas klassbibliotek om man vill skriva en grafisk applikation. För in
och utmatningar kan vi enkelt få hjälp av klassen JOptionPane som är en klass som innehåller metoder
för att visa olika enkla typer av dialogrutor.
Om vi drar oss till minnes det första inmatningsexemplet
import java.util.*;
class KeyboardReading
{
public static void main(String [] arg)
{
Scanner tgb = new Scanner(System.in);
System.out.println("Hur många endollarmynt har du?");
int antalDollar;
antalDollar = tgb.nextInt();
System.out.println("Jaså du har "+ antalDollar + " stycken.");
}
}
Kan det skrivas om till att använda JOptionPane och dialogrutor som
import javax.swing.*;
class KeyboardReading
{
public static void main(String [] arg)
{
String inmatning =
JOptionPane.showInputDialog("Hur många dollar har du?");
double dollars;
dollars = Double.parseDouble( inmatning );
JOptionPane.showMessageDialog( null,
"Jaså du har $"+ dollars );
}
}
Radbrytningarna på rad 7 och 13 är gjorda för läsbarhetens skull.
JOptionPane befinner sig i grafikpaketet javax.swing och därför ser import-satsen ut som den gör.
Inläsningen sker med JOptionPanes medlem showInputDialog som returnerar en text, String.
Inmatningen som görs i dialogrutan ges alltså tillbaka på textform. Vi har här ingen möjlighet att
direkt läsa in talvärden utan är tvungen att läsa in en text, som vi sedan omvandlar till ett tal. Double är
en hjälpklass till den primitiva taltypen double. Double förser oss med hjälpmetoder för att arbeta med
tal av typen double, bland annat metoden parseDouble( String s ) som omvandlar strängen s till
double.
Samtliga enkla typer har en motsvarande komplementerande klass, double-Double, int-Integer, byteByte, char-Character osv.
För att sedan presentera resultaten används showMessageDialog( null, String s);
Uttrycket null betyder inget objekt. showMessageDialog förväntar sig att ett "föräldrafönster" ska äga
dialogrutan, men eftersom vi inte har något föräldrafönster anger vi istället null. Texten s är förstås
den text som ska visas i dialogrutan.