JAVA UTILITIES PACKAGE EN BIT-MANIPULATIE Hoofdstuk 20: JAVA UTILITIES PACKAGE EN BIT-MANIPULATIE
H 20. JAVA UTILITIES PACKAGE AND BIT-MANIPULATION 1. INLEIDING De package java.util bevat klassen om stacks, vectoren, hashtabellen en bitsets te verwerken. Hoewel deze klassen elk een specifieke functie hebben, bieden ze allemaal een mechanisme om gegevens op te slaan en op te halen.
H 20. JAVA UTILITIES PACKAGE EN BIT MANIPULATIE 1. INLEIDING In dit hoofstuk worden enkele klassen en een interface van package java.util besproken: klasse Vector interface Enumeration klasse Stack klasse Hashtable klasse Properties klasse BitSet
2. KLASSE Vector EN INTERFACE Enumeration Klasse java.util.Vector Vector is een groeibare array. M.a.w. tijdens runtime kan de lengte van de array groter en kleiner worden. Vector bevat een capaciteit Capaciteit geeft het aantal objecten aan die een vector kan bevatten. M.a.w. het aantal objecten van een vector is steeds kleiner of gelijk aan de capaciteit.
2. KLASSE Vector: capaciteit Als de capaciteit overtroffen wordt, dan breidt ze zich automatisch uit, om de bijkomende gegevens te kunnen opvangen Ze breidt zich uit met de "capacity increment" capaciteit = capaciteit + "capacity increment" OF indien de "capacity increment" niet werd gedefinieert dan breidt ze zich uit met de "default capacity increment". De "default capacity increment" verdubbelt de capaciteit.
2. KLASSE Vector: constructoren Er zijn vier constructoren voor de klasse Vector: vector1 = new Vector() Creëert een lege vector met capaciteit van 10 objecten en met de "default capacity increment" ("capacity increment" = 0). vector2 = new Vector(collection) Creëert een vector, gevuld met de objecten van de collection. De capaciteit is het aantal objecten die in de collection staan. De vector bevat de "default capacity increment". Collections wordt in het volgend hoofdstuk uitgelegd.
2. KLASSE Vector: constructoren vector3 = new Vector(lengte) Creëert een lege vector met capaciteit het aantal objecten dat door de integer "lengte" wordt aangegeven en met de "default capacity increment". vector4 = new Vector(lengte, toename) Idem als vector3, behalve met de "capacity increment" dat door de integer "toename" wordt aangegeven.
2. KLASSE Vector: methodes add en insertElementAt Methode add add(object) "object" wordt op het einde van de Vector toegevoegd. add(plaats, object) De objecten vanaf index "plaats" worden met één plaats opgeschoven. Vervolgens wordt "object" toegevoegd op index "plaats" in de Vector . Methode insertElementAt insertElementAt(object, plaats) Idem als de methode add(plaats, object)
2. KLASSE Vector: methode add Vector vector = new Vector(); //capaciteit = 10 elementen vector.add( "magenta" ); magenta 0 1 2 ... 9 vector.add( "cyan" ); // "cyan" wordt op het einde van // de vector toegevoegd, dus op index 1 magenta cyan try { vector.add( 1, "green" ); } //op index 1 wordt // "green" toegevoegd catch (ArrayIndexOutOfBoundsException exception) { exception.printStackTrace(); } magenta green cyan 0 1 2 3 ... 9
2. KLASSE Vector: methode get en type-casting get(plaats) De referentie van het object op index "plaats" wordt teruggegeven. TYPE-CASTING Alles wat we in een vector plaatsen, wordt eerst geconverteerd naar een object van klasse Object. Hieruit volgt dat we alles erin kunnen plaatsen wat we willen. Maar om er iets uit te krijgen, moeten we eerst weten waarnaar het moet worden gecast!
2. KLASSE Vector: methode get en type-casting Vector vector = new Vector(); String mijnString = "red"; JButton mijnButton = new JButton("kleur"); Integer mijnGetal = new Integer(5); vector.add(mijnString); vector.add(mijnButton); vector.add(mijnGetal); try { String nieuweString = (String) vector.get(0); JButton nieuweButton = (JButton) vector.get(1); Integer nieuwGetal = (Integer) vector.get(2); }//werpt een exception indien index < 0 of index >= size() catch (ArrayIndexOutOfBoundsException exception) { exception.printStackTrace(); }
2. KLASSE Vector: methodes set en setElementAt Methode set: set(plaats, object) Op index "plaats" wordt het object gewijzigd door het "object". Het vorig object wordt teruggegeven. Methode setElementAt setElementAt(object, plaats) Idem als de methode set(plaats, object), behalve dat deze methode niks teruggeeft (void).
2. KLASSE Vector: methodes set en setElementAt Vector vector = new Vector(); vector.add( "magenta" ); vector.add( "green" ); try { String color = (String) vector.set(1,"red"); System.out.println( "Het oorspronkelijk kleur was: " + color + "\n" ); vector.setElementAt("white",0); }//werpt een exception indien index<0 of index >= size() catch (ArrayIndexOutOfBoundsException exception) { exception.printStackTrace();} De vector bevat, na de set en setElementAt methodes, op index 0 het object "white" en op index 1 "red". Op het scherm wordt weergegeven: Het oorspronkelijke kleur was: green
2. KLASSE Vector: methodes firstElement en lastElement Methode firstElement Geeft de referentie van het eerste object van de Vector terug Methode lastElement Geeft de referentie van het laatste object van de Vector terug // het eerste en laatste element weergeven try { System.out.println( "First element: " + vector.firstElement() ); System.out.println( "Last element: " + vector.lastElement() ); } // catch exception indien de vector leeg is catch ( NoSuchElementException exception ) { exception.printStackTrace(); }
2. KLASSE Vector: methode indexOf indexOf(object) geeft de index terug waar het "object" het eerst in de Vector voorkomt. Indien het "object" niet voorkomt, dan geeft de methode –1 terug. indexOf(object,plaats) geeft de index terug waar het "object", vanaf index "plaats", het eerst in de Vector voorkomt.
2. KLASSE Vector: methodes contains en indexOf Methode contains contains(object) Geeft true terug indien het "object" in de Vector voorkomt, anders false. // bevat de vector al dan niet "red"? if ( vector.contains( "red" ) ) System.out.println( "\n\"red\" found at index " + vector.indexOf( "red" ) + "\n" ); else System.out.println( "\n\"red\" not found\n" );
2. KLASSE Vector: methode remove remove(object) - Verwijdert het "object" in de Vector. - Alle objecten die na het verwijderd object staan, worden met één plaats naar voren verschoven. - Indien het "object" meerdere keren in de Vector voorkomt dan wordt enkel het eerst voorkomende "object" verwijdert. - Deze methode geeft true terug indien het object in de Vector voorkwam, anders false.
2. KLASSE Vector: methodes (verwijderen van objecten) Methode remove remove(plaats) - Op index "plaats" wordt het object uit de Vector verwijderd. - Deze methode geeft de referentie van het verwijderd object terug. Methode removeElementAt removeElementAt(plaats) Idem als de methode remove(plaats) behalve dat deze methode niks teruggeeft (void). Methode removeAllElements removeAllElements() Alle objecten worden uit de Vector verwijderd. De size wordt op 0 geplaatst.
2. KLASSE Vector: methode remove, removeElementAt en removeAllElements Voorbeeld: ... vector.remove("red"); try { String verwijderdeKleur = (String) vector.remove(1); vector.removeElementAt(0); } // catch exception indien de index < 0 of index >= size() catch (ArrayIndexOutOfBoundsException exception) exception.printStackTrace(); vector.removeAllElements();
2. KLASSE Vector: methodes size en capacity Methode size Geeft het aantal objecten in de Vector terug Methode capacity Geeft de capaciteit van de Vector terug capaciteit = aantal objecten dat kan opgeslagen worden zonder meer geheugenruimte te moeten alloceren
2. KLASSE Vector: methodes trimToSize en setSize Methode trimToSize De capaciteit wordt gelijkgesteld aan de size. Methode setSize setSize(nieuweSize) - De size wordt gelijkgesteld aan "nieuweSize" - Indien de size werd verlaagd, dan worden alle objecten vanaf index "nieuweSize" verwijderd. - Indien de size werd verhoogd, dan worden er nieuwe null-objecten op het einde van de Vector toegevoegd (van index "vorigeSize" tot index "nieuweSize").
2. KLASSE Vector: methode ensureCapacity Stelt de capaciteit van de Vector in. Garandeert dat de Vector een minimum capaciteit heeft. Als de originele capaciteit groter is dan de nieuwe, dan blijft de capaciteit ongewijzigd.
2. KLASSE Vector: methode ensureCapacity als de originele capaciteit kleiner is dan de nieuwe, dan wordt de capaciteit: als "capacity increment" = 0 ("default capacity increment"): als (nieuwe capaciteit > 2 * originele capaciteit) dan capaciteit = nieuwe capaciteit anders capaciteit = 2 * originele capaciteit als "capacity increment" > 0 : als (nieuwe capaciteit > "capacity increment" + originele capaciteit) anders capaciteit = "capacity increment" + originele capaciteit
2. OEFENING Bepaal de uitvoer van het volgend programma: Vector vector = new Vector(); vector.add( "magenta" ); vector.add( "cyan" ); vector.add("red"); System.out.println( "\n1. Size: " + vector.size() + " Capacity: " + vector.capacity() ); vector.trimToSize(); System.out.println( "\n2. Size: " + vector.size() + vector.add( "magenta" ); System.out.println( "\n3. Size: " + vector.size() +
2. OPLOSSING 2. Size: 3 Capacity: 3 3. Size: 4 Capacity: 6 Vector vector = new Vector(); vector.add( "magenta" ); vector.add( "cyan" ); vector.add("red"); System.out.println( "\n1. Size: " + vector.size() + " Capacity: " + vector.capacity() ); vector.trimToSize(); System.out.println( "\n2. Size: " + vector.size() + vector.add( "magenta" ); System.out.println( "\n3. Size: " + vector.size() + 1. Size: 3 Capacity: 10 2. Size: 3 Capacity: 3 3. Size: 4 Capacity: 6
2. OEFENING Bepaal de uitvoer van het volgend programma: Vector vector = new Vector(5,8); vector.add( "magenta" ); vector.add( "cyan" ); vector.add("red"); System.out.println( "\n1. Size: " + vector.size() + " Capacity: " + vector.capacity() ); vector.trimToSize(); vector.add( "magenta" ); System.out.println( "\n2. Size: " + vector.size() + vector.ensureCapacity(18); System.out.println( "\n3. Size: " + vector.size() +
2. OPLOSSING 2. Size: 4 Capacity: 11 3. Size: 4 Capacity: 19 Vector vector = new Vector(5,8); vector.add( "magenta" ); vector.add( "cyan" ); vector.add("red"); System.out.println( "\n1. Size: " + vector.size() + " Capacity: " + vector.capacity() ); vector.trimToSize(); vector.add( "magenta" ); System.out.println( "\n2. Size: " + vector.size() + vector.ensureCapacity(18); System.out.println( "\n3. Size: " + vector.size() + 1. Size: 3 Capacity: 5 2. Size: 4 Capacity: 11 3. Size: 4 Capacity: 19
2. KLASSE Vector en interface Enumeration private void printVector( Vector vectorToOutput ) { if ( vectorToOutput.isEmpty() ) System.out.print( "vector is empty" ); else { // iterate through the elements System.out.print( "vector contains: " ); Enumeration items = vectorToOutput.elements(); while ( items.hasMoreElements() ) System.out.print( items.nextElement() + " " ); } System.out.println( "\n" ); De methode printVector zal alle objecten in de vector weergeven op het scherm.
2. KLASSE Vector: methodes isEmpty en elements Methode isEmpty Geeft true terug indien de vector leeg is (= size is gelijk aan 0), anders false. Methode elements Geeft een enumeration terug zodat we de vector kunnen doorlopen: alle objecten van index 0 t.e.m. index "size()-1".
2. INTERFACE Enumeration De interface Enumeration bevat twee methodes: hasMoreElements en nextElement Methode hasMoreElement Geeft true terug indien de enumeration nog objecten bevat, anders false. Methode nextElement Geeft de referentie terug van het volgend object in de Vector . Werpt een NoSuchElementException indien er geen objecten meer zijn.
3. KLASSE Stack Klasse java.util.Stack In een stack kunnen we objecten plaatsen (push()) en objecten ophalen (pop()). Stacks werken volgens het LIFO-principe (Last In, First Out), wat betekent dat het laatste object dat we op de stack hebben geplaatst (push()) het eerste is dat we met de methode pop() ontvangen.
De klasse Stack is een subklasse van Vector. Klasse java.util.Stack De klasse Stack is een subklasse van Vector. Dit betekent dat we een stack kunnen maken en deze kunnen gebruiken zonder ons druk te maken over hoeveel objecten we er uiteindelijk willen in opslaan.
3. KLASSE Stack: constructor Er is één constructor voor de klasse Stack: stack1 = new Stack() Creëert een lege stack met capaciteit van 10 objecten en met de "default capacity increment".
3. KLASSE Stack: methodes De Klasse Stack bevat vijf eigen methodes: push, pop, isEmpty, peek en search. Methode push Een object op de stack plaatsen. Methode pop Een object van de stack afhalen. Methode isEmpty Geeft true terug indien de stack leeg is, anders false.
3. KLASSE Stack: methodes Methode peek peek() Geeft de referentie van het object terug dat bovenaan op de stack staat (= top van de stack). Methode search search(object) Geeft een geheel getal terug waarmee we aan de weet komen hoever onder in de stack het "object" zich bevindt. De top van de stack wordt als afstand één beschouwd. Indien het "object" niet voorkomt, dan geeft de methode –1 terug.
Een lege Stack wordt gecreëerd. 3. KLASSE StackTest import java.util.*; public class StackTest { public StackTest() Stack stack = new Stack(); // objecten creëren om in de stack te plaatsen Boolean bool = Boolean.TRUE; Character character = new Character( '$' ); Integer integer = new Integer( 34567 ); String string = "hello"; // push methode gebruiken stack.push( bool ); printStack( stack ); stack.push( character ); printStack( stack ); stack.push( integer ); printStack( stack ); stack.push( string ); printStack( stack ); Een lege Stack wordt gecreëerd. methode push voegt een Object op de top van de Stack toe.
3. KLASSE StackTest // verwijder objecten van de stack try { Object removedObject = null; while ( true ) removedObject = stack.pop(); // gebruik pop methode System.out.println( removedObject.toString() + " popped" ); printStack( stack ); } // catch exception indien methode pop op een lege stack // werd uitgevoerd. catch ( EmptyStackException emptyStackException ) { emptyStackException.printStackTrace(); } //einde constructor StackTest methode pop verwijdert het object dat op de top van de Stack staat.
3. KLASSE StackTest Stack erft van Vector, dus de klasse Stack kan ook de methode elements gebruiken. Alle objecten van de stack worden doorlopen door behulp van Enumeration. private void printStack( Stack stack ) { if ( stack.isEmpty() ) System.out.print( "stack is empty" ); else System.out.print( "stack contains: " ); Enumeration items = stack.elements(); // stack doorlopen while ( items.hasMoreElements() ) System.out.print( items.nextElement() + " " ); } System.out.println( "\n" ); // naar de volgende lijn public static void main( String args[] ) { new StackTest(); } } // einde klasse StackTest De top van de Stack wordt als laatste weergegeven op het scherm.
3. KLASSE StackTest hello 34567 $ true stack contains: true stack contains: true $ stack contains: true $ 34567 stack contains: true $ 34567 hello hello popped 34567 popped $ popped true popped stack is empty java.util.EmptyStackException at java.util.Stack.peek(Stack.java:79) at java.util.Stack.pop(Stack.java:61) at StackTest.<init>(StackTest.java:32) at StackTest.main(StackTest.java:63) hello 34567 $ true
4. KLASSE Hashtable : inleiding Klasse java.util.Hastable Een hash-tabel wijst sleutels toe aan waarden. De waarden en sleutels kunnen gelijk welk Java-object zijn. Vb.: hashtable "Werknemers" sleutel waarde 123 566 411 KETERS SANDRA 899 455 178 WAERLOP JURGEN …
4. KLASSE Hashtable : methode get Aan de hand van een sleutel kunnen we de overeenkomstige waarde ophalen Object get(Object sleutel) Geeft de overeenkomstige waarde terug of geeft null terug indien de sleutel niet in de hash-tabel voorkomt. Werpt een NullPointerException indien de sleutel gelijk is aan null.
4. KLASSE Hashtable : hashing Een hash-tabel is een gegevensstructuur dat gebruik maakt van hashing: De sleutel wordt omgezet naar een array index. Met deze index wordt de waarde opgezocht. Deze basistechniek heet hashing. Indien twee verschillende sleutels dezelfde array index opleveren dan spreekt men van een collision.
4. KLASSE Hashtable : hash bucket Om collisions te voorkomen maakt JAVA gebruik van "hash bucket (= emmer)": De hash-tabel bestaat uit cellen. Elke cel is een "hash bucket". Een koppel sleutel-waarde wordt toegekend aan een bepaalde "bucket". De techniek hashing bepaalt in welke bucket het koppel sleutel-waarde terechtkomt.
4. KLASSE Hashtable : methode put We kunnen een koppel sleutel-waarde in de hash-tabel zetten door de methode put Object put(Object sleutel, Object waarde) Geeft de voorgaande waarde terug of geeft null terug indien de sleutel nog niet in de hash-tabel voorkwam. Werpt een NullPointerException indien de sleutel of de waarde gelijk is aan null.
4. KLASSE Hashtable : capaciteit en laadfactor Hash-tabellen hebben een capaciteit en een laadfactor. De capaciteit is het aantal emmers ("buckets") dat de hash-tabel bevat. De laadfactor is een getal tussen 0 en 1. Deze vertelt ons hoe vol een hash-tabel kan worden voordat de capaciteit wordt verhoogd. Als we de laadfactor niet opgeven wanneer we een hash-tabel creëren, wordt deze ingesteld op 0.75. Dit betekent dat als het aantal vermeldingen 75% van de capaciteit bereikt, de capaciteit wordt verhoogd met de methode rehash().
4. KLASSE Hashtable: constructoren Er zijn meerdere constructoren voor de klasse Hashtable: hashtable1 = new Hashtable() Creëert een lege hash-tabel met een capaciteit van 11 en een laadfactor 0.75. hashtable2 = new Hashtable(capaciteit) Creëert een lege hash-tabel met een capaciteit aangegeven door de integer “capaciteit“ en een laadfactor 0.75. Hashtable3 = new Hashtable(capaciteit, laadfactor) Creëert een lege hash-tabel met een capaciteit aangegeven door de integer “capaciteit“ en een laadfactor aangegeven door de float “laadfactor“.
4. KLASSE Hashtable : inleiding Hash-tabellen kunnen meer dan één gegevenstype opslaan. Terwijl String- en StringBuffer-objecten alleen tekens kunnen bevatten en arrays alleen elementen van hetzelfde type kunnen hebben, kunnen we de gegevenstypen, die zijn opgeslagen in een hash-tabel, combineren.
4. KLASSE Hashtable: VOORBEELD Van een ingegeven zin wordt er afgebeeld hoeveel keer een bepaald woord erin voorkomt. De sleutels zijn de woorden. De overeenkomstige waarden zijn gehele getallen. Deze getallen stellen het aantal keer, dat een woord in de zin voorkomt, voor.
4. KLASSE Hashtable: VOORBEELD
Een lege hashable creëren. 4. KLASSE WordTypeCount import java.util.*; … public class WordTypeCount extends JFrame { private Hashtable table; public WordTypeCount() table = new Hashtable(); Een lege hashable creëren.
4. KLASSE WordTypeCount goButton = new JButton( "Go" ); goButton.addActionListener( new ActionListener() { // anonieme innerklasse public void actionPerformed( ActionEvent event ) { createTable(); display.setText( createOutput() ); } } // einde anonieme innerklasse ); // einde oproep naar addActionListener … }// einde constructor Indien de gebruiker op de button "Go" klikt, dan zullen de methodes createTable en createOutput opgeroepen worden.
Uitleg: zie volgende slide 4. KLASSE WordTypeCount // hash-tabel opvullen met invoer van de gebruiker private void createTable() { String input = inputField.getText(); StringTokenizer words = new StringTokenizer( input, " \n\t\r" ); while ( words.hasMoreTokens() ) String word = words.nextToken().toLowerCase(); // indien de sleutel "word" reeds in de hashtable "table" voorkomt. if ( table.containsKey( word ) ) // overeenkomstige waarde opvragen en met één verhogen: Integer count = (Integer) table.get( word ); table.put( word, new Integer( count.intValue() + 1 ) ); } else // de sleutel "word" en waarde 1 in de hash-tabel zetten table.put( word, new Integer( 1 ) ); } // einde while } // einde methode createTable Uitleg: zie volgende slide
De methode intValue zet de waarde van de Integer om naar een int. 4. KLASSE WordTypeCount if ( table.containsKey( word ) ) { // overeenkomstige waarde opvragen en met één verhogen: Integer count = (Integer) table.get( word ); table.put( word, new Integer( count.intValue() + 1 ) ); } else // de sleutel "word" en waarde 1 in de hash-tabel zetten table.put( word, new Integer( 1 ) ); Indien het woord "word" (= sleutel) reeds in de hash-tabel voorkomt, dan wordt zijn overeenkomstige waarde (count) met één verhoogd en terug in de hash-tabel geplaatst. Anders wordt het woord "word" (=sleutel) en de waarde 1 in de hash-tabel geplaatst. De methode intValue zet de waarde van de Integer om naar een int.
4. KLASSE WordTypeCount // string creëren die alle sleutels en overeenkomstige waarden // van de hash-tabel bevat private String createOutput() { String output = ""; Enumeration keys = table.keys(); // de sleutels doorlopen while ( keys.hasMoreElements() ) Object currentKey = keys.nextElement(); // het koppel sleutel-waarde toevoegen aan de string output += currentKey + "\t" + table.get( currentKey ) + "\n"; } output += "size: " + table.size() + "\n"; output += "isEmpty: " + table.isEmpty() + "\n"; return output; } // einde methode createOutput Geeft een enumeration terug zodat we de hash-table kunnen doorlopen. De enumeration bevat alle sleutels. Geeft het aantal koppels sleutels-waarden, die de hash-tabel bevat, terug
5. KLASSE Properties : inleiding Klasse java.util.Properties Een properties-tabel is een hash-tabel waarbij de sleutels altijd een String zijn. De klasse Properties is een subklasse van Hashtable. Doel van Properties: deze klasse biedt een eenvoudige manier om op tekst gebaseerde gegevens van bestand te laden en op te slaan.
5. KLASSE Properties : methode getProperty Aan de hand van een sleutel kunnen we de overeenkomstige waarde ophalen String getProperty(String sleutel) Geeft de overeenkomstige waarde terug of geeft null terug indien de sleutel niet in de properties-tabel voorkomt.
5. KLASSE Properties : methode setProperty We kunnen een koppel sleutel-waarde in de property zetten door de methode setProperty Object setProperty(String sleutel, String waarde) Geeft de voorgaande waarde terug of geeft null terug indien de sleutel nog niet in de properties-tabel voorkwam.
5. KLASSE Properties: VOORBEELD De gebruiker kan op de volgende buttons klikken: Put: koppel sleutel-waarde toevoegen of een waarde wijzigen. Clear: de properties-tabel wissen. Get property: de overeenkomstige waarde opvragen. Save: de properties-tabel bewaren op bestand. Load: de properties-tabel laden van bestand.
5. KLASSE Properties: VOORBEELD
5. KLASSE Properties: VOORBEELD
5. KLASSE PropertiesTest import java.io.*; import java.util.*; ... public class PropertiesTest extends JFrame { private Properties table; // opmaak van GUI om de Property-tabel uit te testen public PropertiesTest() table = new Properties(); northSubPanel.add( new JLabel( "Property value" ) ); valueField = new JTextField( 10 ); northSubPanel.add( valueField ); northSubPanel.add( new JLabel( "Property name (key)" ) ); nameField = new JTextField( 10 ); northSubPanel.add( nameField ); Een lege properties-tabel creëren.
5. KLASSE PropertiesTest ... JButton putButton = new JButton( "Put" ); southPanel.add( putButton ); putButton.addActionListener(new ActionListener() { // anonieme innerklasse // zet koppel naam-waarde in Properties tabel public void actionPerformed( ActionEvent event ) { Object value = table.setProperty( nameField.getText(), valueField.getText() ); if ( value == null ) showstatus( "Put: " + nameField.getText() + " " + valueField.getText() ); else valueField.getText() + "; Replaced: " + value ); listProperties(); } } // einde anonieme innerklasse ); Indien de gebruiker op de button "Put" klikt dan zal een koppel sleutel-waarde worden toegevoegd of indien de sleutel reeds bestaat in de properties-tabel dan zal zijn overeenkomstige waarde gewijzigd worden.
5. KLASSE PropertiesTest JButton clearButton = new JButton( "Clear" ); southPanel.add( clearButton ); clearButton.addActionListener( new ActionListener() { // anonieme innerklasse // methode clear gebruiken om de properties-tabel te wissen. public void actionPerformed( ActionEvent event ) { table.clear(); showstatus( "Table in memory cleared" ); listProperties(); } } // einde anonieme innerklasse ); // einde oproep naar addActionListener De methode clear wist de properties-tabel
5. KLASSE PropertiesTest JButton getPropertyButton = new JButton( "Get property" ); ... // methode getProperty gebruiken om de overeenkomstige waarde // op te halen. public void actionPerformed( ActionEvent event ) { Object value = table.getProperty( nameField.getText() ); if ( value != null ) showstatus( "Get property: " + nameField.getText() + " " + value.toString() ); else showstatus( "Get: " + nameField.getText() + " not in table" ); listProperties(); } } // einde anonieme innerklasse ); Indien de gebruiker de sleutel ingeeft en op de button "Get property" klikt dan zal, indien de sleutel in de properties-tabel voorkomt, de overeenkomstige waarde worden weergegeven.
5. KLASSE PropertiesTest JButton saveButton = new JButton( "Save" ); ... public void actionPerformed( ActionEvent event ) { // de inhoud van de properties-tabel bewaren op bestand try { FileOutputStream output = new FileOutputStream( "props.dat" ); table.store( output, "Sample Properties" ); output.close(); listProperties(); } // problemen met file output opvangen: catch( IOException ioException ) { ioException.printStackTrace(); } } } // einde anonieme innerklasse ); Deze methode store zal alle koppels sleutels-waarden van de properties-tabel "table" bewaren op het bestand "props.dat".
5. KLASSE PropertiesTest JButton loadButton = new JButton( "Load" ); ... public void actionPerformed( ActionEvent event ) { // de inhoud van de tabel laden try { FileInputStream input = new FileInputStream( "props.dat" ); table.load( input ); input.close(); listProperties(); } // problemen met file output opvangen: catch( IOException ioException ) { ioException.printStackTrace();} } } // einde anonieme innerklasse ); Deze methode load zal alle koppels sleutels-waarden van het bestand "props.dat" laden in de properties-tabel "table".
5. KLASSE PropertiesTest // de koppels sleutel-waarden van de properties-tabel weergeven public void listProperties() { StringBuffer buffer = new StringBuffer(); String name, value; Enumeration enumeration = table.propertyNames(); while ( enumeration.hasMoreElements() ) name = enumeration.nextElement().toString(); value = table.getProperty( name ); buffer.append( name ).append( '\t' ); buffer.append( value ).append( '\n' ); } displayArea.setText( buffer.toString() ); Geeft een enumeration terug zodat we de properties-tabel kunnen doorlopen. De enumeration bevat alle sleutels.
6. BIT-MANIPULATIES EN BITWISE OPERATOREN Inleiding Bit = de allerkleinste geheugeneenheid, die een 0 of een 1 kan bevatten. Byte = (in het algemeen) elementaire geheugeneenheid van een computer. Een byte is opgebouwd uit 8 bits.
6. BIT-MANIPULATIES EN BITWISE OPERATOREN Inleiding Bit-manipulatie is nodig indien we rechtstreeks met de hardware wensen te communiceren (bv. we willen een operating system, netwerk software, … , programmeren.) We voeren bit-manipulatie uit door gebruik te maken van bitwise operatoren.
Bitwise EN-operator (&) 6. BITWISE OPERATOREN Bitwise EN-operator (&) De bitwise en-operator & heeft als resultaat 1 als beide bits gelijk zijn aan 1. Als één van beide bits gelijk is aan 0, of beide zijn gelijk aan 0, dan levert de bitwise en-operator & ook 0 op.
Bitwise EN-operator (&) 6. BITWISE OPERATOREN Bitwise EN-operator (&) Voorbeeld: 100 & 12 geeft 4 als resultaat: 1100100 // binaire voorstelling van 100 & 1100 // binaire voorstelling van 12 ------------------- 100 // binaire voorstelling van 4 100 & 12 geeft ook 1 als resultaat: de meest significante bit van het geheel getal 4 is 1 if (( 100 & 12 ) == 0) …
Bitwise inclusieve OF operator (|) 6. BITWISE OPERATOREN Bitwise inclusieve OF operator (|) De bitwise inclusieve of-operator | heeft als resultaat 1 als één van beide bits gelijk is aan 1, of beide zijn gelijk aan 1. Als beide bits gelijk zijn aan 0, dan levert de bitwise inclusieve of-operator | 0 op.
Bitwise exclusieve OF operator (^) 6. BITWISE OPERATOREN Bitwise exclusieve OF operator (^) De bitwise exclusieve of-operator ^ heeft als resultaat 1 als één van beide bits gelijk is aan 1. Als beide bits gelijk zijn aan 0 of 1, dan levert de bitwise exclusieve of-operator ^ 0 op.
"Left shift" (<<) 6. BITWISE OPERATOREN x << y De bits van x worden y-maal naar links verschoven. De bits worden achteraan aangevuld met 0. voorbeeld: 1 << 6 De voorstelling van getal 1 in bits is: 00000000 00000000 00000000 00000001 Er worden 6 plaatsen naar links verschoven: 00000000 00000000 00000000 01000000
"Signed rigth shift" (>>) 6. BITWISE OPERATOREN "Signed rigth shift" (>>) x >> y De bits van x worden y-maal naar rechts verschoven. Indien x negatief is dan worden de bits vooraan aangevuld met 1, anders met 0. "Unsigned rigth shift " (>>>) x >>> y De bits van x worden y-maal naar rechts verschoven. De bits worden vooraan aangevuld met 0.
"bitwise complement" (~) 6. BITWISE OPERATOREN "bitwise complement" (~) Alle 0 bits worden omgezet naar 1 en alle 1 bits worden omgezet naar 0.
6. BIT-MANIPULATIES EN BITWISE OPERATOREN Voorbeeld 1 Van een ingegeven geheel getal zijn overeenkomstige bit-representatie weergeven.
6. KLASSE PrintBits ... public class PrintBits extends JFrame { private JTextField outputField; public PrintBits() { ... container.add( new JLabel( "Enter an integer " ) ); JTextField inputField = new JTextField( 10 ); public void actionPerformed( ActionEvent event ) int value = Integer.parseInt( event.getActionCommand() ); outputField.setText( getBits( value ) ); } } // einde anonieme innerklasse ); } // einde constructor Zet een String om naar een int, vervolgens wordt de int doorgegeven aan de private methode getBits. Deze methode geeft de bit-represenatie van de int terug.
6. KLASSE PrintBits // geeft de bit-representatie van de int "value" terug private String getBits( int value ) { // creëert een int met het meest linkse bit 1. De overige 31 // bits zijn 0. int displayMask = 1 << 31; StringBuffer buffer = new StringBuffer( 35 ); // buffer // voor output // Voor elke bit 0 of 1 aan de buffer toevoegen for ( int bit = 1; bit <= 32; bit++ ) { // displayMask gebruiken om een bit af te zonderen buffer.append( ( value & displayMask ) == 0 ? '0' : '1' ); value <<= 1; // shift value met één positie naar links if ( bit % 8 == 0 ) buffer.append( ' ' ); // Na elke 8 bits een spatie toevoegen } return buffer.toString(); } // einde methode getBits ... 1 << 31 is gelijk aan 10000000 00000000 00000000 00000000 Uitleg: zie volgende slide
UITLEG: buffer.append( ( value & displayMask ) == 0 ? '0' : '1' ); value <<= 1; // m.a.w. value = value << 1; Stel dat value gelijk is aan 2 000 000 000 (01110111 00110101 10010100 00000000) Wanneer value en displayMask (1<<31) vergeleken worden met de bitwise EN-operator (&) wordt de meest significante bit van het resultaat teruggegeven. 01110111 00110101 10010100 00000000 & 10000000 00000000 0000000 00000000 is 00000000 00000000 0000000 00000000 0 value = value << 1, dus de bits van value worden met één plaats naar links opgeschoven: 11101110 01101011 00101000 00000000. 11101110 01101011 00101000 00000000 & 10000000 00000000 0000000 00000000 is 10000000 00000000 0000000 00000000 1 Etc.
6. BIT-MANIPULATIES EN BITWISE OPERATOREN Voorbeeld 2 De gebruiker kan op de volgende buttons klikken: And: het resultaat van de bitwise en-operator & wordt in bits en in geheel getal weergegeven. Analoog voor Inclusive OR, Exclusive OR en Complement.
6. BIT-MANIPULATIES EN BITWISE OPERATOREN
6. KLASSE MicsBitOps ... public class MiscBitOps extends JFrame {... public MiscBitOps() JButton andButton = new JButton( "AND" ); public void actionPerformed( ActionEvent event ) { setFields(); resultField.setText( Integer.toString( value1 & value2 ) ); bits3Field.setText( getBits( value1 & value2 ) ); } } // einde anonieme innerklasse ); JButton inclusiveOrButton = new JButton( "Inclusive OR" ); resultField.setText( Integer.toString( value1 | value2 ) ); bits3Field.setText( getBits( value1 | value2 ) ); (value1 & value2) heeft een geheel getal als resultaat.
6. KLASSE MicsBitOps JButton exclusiveOrButton = new JButton( "Exclusive OR" ); ... resultField.setText( Integer.toString( value1 ^ value2 ) ); bits3Field.setText( getBits( value1 ^ value2 ) ); } } // einde anonieme innerklasse ); JButton complementButton = new JButton( "Complement" ); int value = Integer.parseInt( input1Field.getText() ); resultField.setText( Integer.toString( ~value ) ); bits1Field.setText( getBits( value ) ); bits3Field.setText( getBits( ~value ) ); } // end constructor private void setFields() { value1 = Integer.parseInt( input1Field.getText() ); value2 = Integer.parseInt( input2Field.getText() ); bits1Field.setText( getBits( value1 ) ); bits2Field.setText( getBits( value2 ) ); } ...
6. BITWISE TOEKENNING OPERATOREN
6. Voorbeeld 3: KLASSE BitShift ... int value = Integer.parseInt( valueField.getText() ); value <<= 1; ... value >>= 1; ... value >>>= 1; ... Starten met getal –2147483648 Één positie naar rechts opschuiven (signed) opschuiven (unsigned)
Klasse java.util.BitSet 7. KLASSE BITSET Klasse java.util.BitSet BitSet is een groeibare array van bits. Deze bits stellen vlaggen voor die op true ( = 1 ) of op false ( = 0 ) staan.
7. KLASSE BITSET: bitwise operatoren Bitwise operatoren kunnen op bitsets als volgt worden toegepast: Stel dat b1 en b2 bitsets zijn: b1.and(b2); De bitwise EN-operator wordt bit per bit uitgevoerd (b1[0] & b2[0], b1[1]&b2[1],…) en het resultaat wordt bewaard in de bitset b1. b1.or(b2); //Bitwise inclusieve OF operator b1.xor(b2); //Bitwise exclusieve OF operator
7. KLASSE BitSet: constructoren Er zijn twee constructoren voor de klasse BitSet: bitSet1 = new BitSet() Creëert een lege bitset (= alle bits staan op false). In het geheugen is er reeds plaats om 64 bits te bewaren (index 0 t.e.m. 63). bitSet2 = new BitSet(aantal) Creëert een lege bitset. In het geheugen is er reeds plaats om “aantal“ bits te bewaren.
7. KLASSE BitSet: voorbeelden van methoden Voorbeelden van methoden van de klasse BitSet: bitSet1 = new BitSet(); int size = bitSet1.size(); // size = 64 int lengte = bitSet1.length(); // lengte = 0 // (= logische size = geeft de index van de hoogste bit die op true staat + 1 ) bitSet1.set(3); //zet de bit op index 3 op true bitSet1.set(10); //zet de bit op index 10 op true; lengte = bitSet1.length(); // lengte = 11 if (bitSet1.get(3)) ... // geeft true terug indien de bit //op index 3 op true staat, anders false bitSet1.clear(3); //zet de bit op index 3 op false.
7. KLASSE BitSet: voorbeelden van methoden Voorbeelden van methoden van de klasse BitSet: bitSet1 = new BitSet(); bitSet2 = new BitSet(500); // bitSet1.toString() geeft “{}“ terug. bitSet1.set(4); bitSet1.set(10); // bitSet1.toString() geeft “{4,10}“ terug. bitSet2.set(4); bitSet2.set(10); if (bitSet1.equals(bitSet2)) ... // geeft true terug omdat // de bitsets identiek zijn
7. KLASSE BitSetTest Voorbeeld Alle priemgetallen tussen 2 en 1023 worden weergegeven. Tevens kan de gebruiker een getal ingeven en krijgt op het scherm te zien of het getal al dan niet een priemgetal is.
7. KLASSE BitSetTest
Een lege bitset wordt gecreëerd met size 1024 7. KLASSE BitSetTest import java.util.*; ... public class BitSetTest extends JFrame { private BitSet sieve; public BitSetTest() // schermopmaak (constructor) super( "BitSets" ); sieve = new BitSet( 1024 ); Een lege bitset wordt gecreëerd met size 1024
7. KLASSE BitSetTest // textfield waar de gebruiker een getal kan ingeven tussen 2 // en 1023. Indien de gebruiker een getal ingeeft groter dan // 1023 dan krijgt hij als bericht dat het getal geen // priemgetal is! inputField = new JTextField( 10 ); ... inputField.addActionListener( new ActionListener() { // innerklasse // bepaalt indien het getal al dan niet een priemgetal is public void actionPerformed( ActionEvent event ) { int value = Integer.parseInt( inputField.getText() ); if ( sieve.get( value ) ) statusLabel.setText( value + " is a prime number" ); else statusLabel.setText(value + " is not a prime number"); } } // einde innerklasse ); // einde oproep addActionListener Geeft true terug indien de bit op index "value" op true staat, anders false.
De methoden get, set en clear werpen een IndexOutOfBoundsException 7. KLASSE BitSetTest ... // geeft de size van de bitset terug int size = sieve.size(); // zet alle bits van 2 to 1023 op true for ( int i = 2; i < size; i++ ) sieve.set( i ); // voer Sieve van Eratosthenes uit int finalBit = ( int ) Math.sqrt( size ); for ( int i = 2; i < finalBit; i++ ) if ( sieve.get( i ) ) for ( int j = 2 * i; j < size; j += i ) sieve.clear( j ); De methoden get, set en clear werpen een IndexOutOfBoundsException indien hun argument negatief is. Zet de bit op index "i" op true Zet de bit op index "j" op false
7. KLASSE BitSetTest // Geeft alle priemgetallen tussen 2 en 1023 weer int counter = 0; for ( int i = 2; i < size; i++ ) if ( sieve.get( i ) ) { primesArea.append( String.valueOf( i ) ); primesArea.append( ++counter % 7 == 0 ? "\n" : "\t" ); } ...