Java Tricks

Aus SibiWiki
Version vom 23. Januar 2022, 18:08 Uhr von Akaibel (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen


Hier geht es um wichtige Tricks für die Java-Entwicklung.

Tricks für die Eclipse-Entwicklung: Eclipse Tricks

Strings vergleichen

Das Vergleichen von Strings führt oft zu Frustration, weil Java Strings (angeblich...) nicht als gleich erkennt. Meist sieht ein Vergleich dann so aus:


  // **** FALSCH!!!! ****
  String string1 = "Meier";
  String string2 = "Meier";
  if(string1 == string2){...}
  if(string1 != string2){...}

Wichtig: Strings sind OBJEKTE!!! D.h. ein Vergleich mit == (bzw. !=) funktioniert nur, wenn es sich um genau das gleiche OBJEKT handelt! Das ist z.B. nicht der Fall, wenn der String s1 = "Meier"; an einer Stelle gespeichert ist und der String s2 = "Meier" an einer anderen Stelle. Strings muss man mithilfe der Methode equals() vergleichen. Dann wird der Wert des Strings betrachtet und man erhält die gewünschte Gleichheit.


  // **** RICHTIG!!!! ****
  String string1 = "Meier";
  String string2 = "Meier";
  if(string1.equals(string2)){...}
  if(string1.equals(string2) == false){...}

Eingabe / Ausgabe von int, double und String

Mithilfe der Klasse JOptionPane kann man sehr einfach Eingaben vom Nutzer abfragen bzw. dem Nutzer eine Meldung zeigen.

Damit man sich bei der Nutzung der Klasse JOptionPane nicht vertut, sind die wichtigsten Funktion Abfragen / Meldungen in der folgenden Convenience-Klasse IO.java zusammengefasst. Die Klasse kann man entweder komplett kopieren oder einzelne Methoden.

Aufgerufen werden die Methoden beispielsweise so:


 int ganzeZahl = IO.getInt("ganze Zahl eingeben");
 System.out.println(ganzeZahl);

Hier der komplette Quelltext der Klasse IO.java:


 import javax.swing.JOptionPane;

 public class IO {

   public static  String getString(String pMessage){
       String ergebnis = JOptionPane.showInputDialog(pMessage);
       return ergebnis;
   }
  
   public static  int getInt(String pMessage){
       String zahlString = JOptionPane.showInputDialog(pMessage);
       int zahl = Integer.parseInt(zahlString);
       return zahl;
   }

   public static  double getDouble(String pMessage){
       String zahlString = JOptionPane.showInputDialog(pMessage);
       double zahl = Double.parseDouble(zahlString);
       return zahl;
   }
   
   public static  boolean getYesNo(String pMessage){
       int ergebnis = JOptionPane.showConfirmDialog(null, pMessage);
       return (ergebnis == JOptionPane.YES_OPTION);
   }
   
   public static  void show(String pMessage){
       JOptionPane.showMessageDialog(null, pMessage);
   }
 }

Mit einer for-Schleife eine Liste durchlaufen

Mit while-Schleifen Listen zu durchlaufen nervt, weil man ständig das next() vergisst und dann eine Endlosschleife hat!

Deswegen ist es sicherer, Listen mit einer for-Schleife zu durchlaufen.

Beispiel:


 public void alleAusgeben(List<Person> personenListe){
    for(personenListe.toFirst(); personenListe.hasAccess(); personenListe.next()){
       Person aktuellePerson = personenListe.getObject();
       System.out.println(aktuellePerson.getName());
    }
 }

... und jetzt für "echtes" Java...

Wenn man richtig Java programmiert (d.h. ohne Zentralabitur-Schnittstellen...), dann geht das sogar noch einfacher. Man benutzt dann am besten parametrisierte Klassen.

Beispiel:


 //personenVector ist parametrisiert
 //d.h. personenVector darf nur Objekte vom Typ Person enthalten!
 private Vector<Person> personenVector;

 public void alleAusgeben(){
    for(Person aktuellePerson : personenVector){
       System.out.println(aktuellePerson.getName());
    }
 }

Datum und Uhrzeit ausgeben

Hier ein Beispiel, wie in Java Datum und Uhrzeit des Systems ausgelesen und angemessen formatiert werden können.


  import java.text.SimpleDateFormat;
  import java.util.Date;

  public class DatumUhrzeitBeispiel {	
     public static void main(String[] args) {

        Date dasDatum = new Date();

        String datumUhrzeitVollstaendig = dasDatum.toString();
        System.out.println(datumUhrzeitVollstaendig);

        SimpleDateFormat formatDatum = new SimpleDateFormat("yyyy-MM-dd");
        String datumString = formatDatum.format(dasDatum);
        System.out.println( "Datum: " + datumString);

        SimpleDateFormat formatUhrzeit = new SimpleDateFormat("HH:mm");
        String uhrzeitString = formatUhrzeit.format(dasDatum);
        System.out.println( "Uhrzeit: " + uhrzeitString);	
     }
  }

Objekte als String (z.B. an die Konsole) ausgeben

Oft steht man vor der Schwierigkeit, dass man ein Objekt mit System.out.println() an die Konsole ausgeben möchte oder sonst eine String-Repräsentation eines Objektes braucht. Das geht am einfachsten (und strategisch am besten!), indem man in der Klasse die Methode toString() definiert. Diese Methode überschreibt dann die Methode toString() der Klasse Object. Z.B. für die Klasse Auftrag:


  import java.util.Date;
  
  public class Auftrag{
  
     private String text;
     private String datumZeit;
  
     public Auftrag(String text){
        this.text = text;
        this.datumZeit = new Date();
     }
  
     // weitere Methoden!!!
  
     // **** JETZT KOMMT DAS WESENTLICHE! ****
     public String toString(){
        return (this.text + ", "+this.datumZeit);
     }
  }

Mit Hilfe der Methode toString() werden die Objekte auch richtig im StackWithViewer (bzw. QueueWithViewer) angezeigt!

Konvertierung von Objekten

TODO

Zufall

Zufallszahlen erzeugen

Die folgende Methode erzeugt ganze Zufallszahlen.


   /**
    * erzeugt eine Zufallszahl zwischen 0 und max
    * (0 und max sind auch moeglich!)
    */
   public int zufallszahl(int max){
       int ergebnis = (int)((max+1)*Math.random());
       return ergebnis;
   }

Zufällige Strings erzeugen

Die folgende Methode erzeugt einen zufälligen String aus Kleinbuchstaben (außer äöüß).


   public String zufallsString(int pLaenge){
       String ergebnis = "";
       for(int i=0; i<pLaenge; i++){
           char zufallsChar = (char)((int)(Math.random()*26)+97);
           ergebnis += zufallsChar;
       }
       return ergebnis;
   }

IP-Adresse des eigenen Rechners auslesen

Um z.B. einen Chatserver aufzusetzen, braucht man die IP-Adresse des eigenen Rechners - denn die muss man den Clients mitteilen können! Die Methode getLocalIPAddress() (s.u.) kann man per Copy/Paste in die eigene Klasse packen.

Damit das funktioniert, braucht man folgende import-statements:


  import java.net.InetAddress;
  import java.net.UnknownHostException;

Und das ist der eigentliche Code:


   /**
    * liest die IP-Adresse des lokalen Rechners aus.
    * @return IP-Adresse des lokalen Rechners.
    */
    public static String getLocalIPAddress(){
      String ipAddress = null;
      try {
         // Holt den Hostnamen
         String localHost = InetAddress.getLocalHost().getHostName();
         // Holt die IP-Adresse
         InetAddress ia = InetAddress.getByName(localHost);
         // liest die Host-Adresse in einen String aus
         ipAddress = ia.getHostAddress().toString();
      } catch (UnknownHostException e) {
         e.printStackTrace();
         ipAddress = "Unknown Host";
      }
      return ipAddress;
    }	

Tastaturabfrage

Tastaturabfragen sind in Java nur möglich, wenn man ein Fenster (z.B. einen JFrame) geöffnet hat und dieser den Fokus hat!

Der folgende Klasse Tastaturabfrage zeigt, wie man eine Tastaturabfrage realisieren kann; einfach den Quellcode in eine Klasse Tastaturabfrage kopieren und dann die main-Methode starten!


 import java.awt.Component;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;

 import javax.swing.JFrame;

 public class Tastaturabfrage {
   private Component component;

   /**
    * der Tastaturabfrage muss man eine Component uebergeben
    * Diese Component sollte sichtbar sein und den Fokus haben
    * nur dann funktioniert's!
    * @param pComponent
    */
   public Tastaturabfrage(Component pComponent){
       this.component = pComponent;
       component.addKeyListener(new KeyListener(){
           public void keyPressed(KeyEvent arg0) {
               char gedrueckterBuchstabe = arg0.getKeyChar();
               int keyCode = arg0.getKeyCode();
               tasteGedrueckt(keyCode, gedrueckterBuchstabe);
           }

           public void keyReleased(KeyEvent arg0) {
           }

           public void keyTyped(KeyEvent arg0) {
           }
       });
   }

   /**
    * diese Methode wird aufgerufen, wenn eine Taste gedrueckt wird!
    * Hier muss man geeigneten Code einfuegen
    * @param keyCode
    * @param gedrueckterBuchstabe
    */
   private void tasteGedrueckt(int keyCode, char gedrueckterBuchstabe) {
       // TODO hier muss man was Sinnvolles tun!
       System.out.println("keyCode: "+keyCode+"; gedrueckterBuchstabe: "+gedrueckterBuchstabe);       
   }
  
   /**
    * die Main-Methode zeigt ein Beispiel,
    * wie man die Tastaturabfrage einsetzen kann.
    * @param args
    */
   public static void main(String[] args) {
       JFrame frame = new JFrame("Testframe");
       frame.setSize(200, 100);
       frame.setVisible(true);
       Tastaturabfrage tf = new Tastaturabfrage(frame);
   }
 }

Speichern im Dateisystem

In Java gibt es die Möglichkeit, Objekte mit ihrem kompletten Status und alle abhängigen Objekte auf einen Schlag im Filesystem zu speichern. D.h. Es wird ein ganzes ObjektCluster gespeichert. Entsprechend kann man diese Objekte auf einen Schlag wieder auslesen.

Voraussetzung: Die Objekte müssen die Schnittstelle Serializable implementieren.

Dafür braucht man die folgende Klasse FileReaderWriter:



import java.io.*;
import java.util.*;

public class FileReaderWriter {
  
   /**
    * Es sollen keine Objekte vom Typ Serializer erzeugt werden.
    */
   private FileReaderWriter(){       
   }
  
   /**
    * speichert ein Objekt - und alle davon abhaengigen Objekte! -
    * in serialisierter Form.
    * Voraussetzung: Das Objekt - und alle davon abhaengigen Objekte -
    * implementieren Serializable
    * @param object
    * @param filename
    */
   public static void saveSerialized( Object object, String filename )
   {
       try
       {
           FileOutputStream file = new FileOutputStream( filename );
           ObjectOutputStream o = new ObjectOutputStream( file );
           o.writeObject  ( object );
           o.writeObject  ( new Date() );
           o.close();
       }
       catch ( IOException e ) { System.err.println("FileReaderWriter.saveSerialized(): "+ e ); }
   }
   /**
    * liest ein serialisiertes Objekt
    * @param filename
    * @return
    */
   public static Object readSerialized( String filename )
     {
       Object result = null;
       try
       {
         FileInputStream file = new FileInputStream( filename );
         ObjectInputStream o = new ObjectInputStream( file );
         result =  o.readObject();
         o.close();
       }
       catch ( IOException e ) {
           System.err.println("FileReaderWriter.readSerialized(): "+ e );
       }
       catch ( ClassNotFoundException e ) {
           System.err.println("FileReaderWriter.readSerialized(): "+ e );
       }
       return result;
     }   
}

Verwendung

Schreiben ins Filesystem:


 FileReaderWriter.saveSerialized(meinObjekt, filename);


Lesen aus dem Filesystem:


MeineKlasse meinObjekt = (MeineKlasse)FileReaderWriter.readSerialized(filename);