Kategorie-Archiv: Java

3. Java-Trend-Barometer veröffentlicht

Expeso hat das dritte Java-Trend-Barometer veröffentlicht. Mit dem Java-Trendbarometer zeigt expeso IT-Verantwortlichen und Java-Experten, wohin der Trend geht, was es Neues gibt und welche Technologien schon reif für den Einsatz sind. Gerade bei den Open Source Frameworks gibt es ständig neue und interessante Entwicklungen, die für Unternehmen auch wirtschaftlich interessant sind.

Um aussagekräftige Ergebnisse mit einem großen Praxisbezug zu erhalten, wurden ausschließlich Java-Experten befragt, die in der Praxis mit den Technologien befasst sind. So ist sichergestellt, dass sich die empfohlenen Technologien auch schon in der täglichen Projektarbeit bewährt haben.

Besonders deutlich stellt sich in der aktuellen Studie der Trend hin zu Application Server dar. Bevorzugte in den vergangenen Jahren die Mehrheit der Java-Entwickler noch einen Servlet-Container zum Deployment ihrer Java Enterprise Applikationen, so haben die Application Server nun deutlich im Unternehmensumfeld zugelegt. Gemäß den Planungen der befragten Experten scheint sich dieser Trend auch weiter fortzusetzen.

Die aktuelle Studie zeigt auch, dass JVM-basierte Skriptsprachen derzeit noch eine untergeordnete Rolle in Unternehmensprojekten spielen. Wie in den vergangenen Studien ist auch diesmal Groovy wieder die beliebteste Skriptsprache.

Welche neuen Technologien haben sich schon in Projekten bewährt? Wir identifizieren mit der vorliegenden Studie innovative Technologien, über die nicht nur viel publiziert wird, sondern die darüber hinaus auch schon tatsächlich im Projektalltag regelmäßig eingesetzt werden und sich bewährt haben. Ganz vorne dabei sind Google Web Toolkit (GWT), Apache Wicket und JSF 2.0.

Zum Trend-Barometer…

Wildcard-Suche in Strings mit Java

Dank Adarshr konnte ich heute ein Problem schnell und elegant lösen.

Ich benötigte eine Methode, um in einem beliebigen String nach einem Substring zu suchen, inklusive einer Wildcard (*). Ich wollte also zum Beispiel nach “*Test*” suchen können, in einem String wie: “Das ist nur ein Test”. Java bietet sowas nativ nicht an, auch die Apache Commons Libs haben dazu keine Lösung, nach einem schnellen Suchlauf bei Google wurde ich dann bei Adarshr fündig. Er hat das Problem gut und kurz gelöst. Ich habe es dann noch um einen Null-Check erweitert und ein paar andere Anpassungen vorgenommen. Die Basis bildet aber weiterhin seine Methode, die ich euch hier nicht vorenthalten möchte.

Falls ihr also mal auf der Suche nach einer Wildcard-Suche für Strings seid, dann erinnert euch an diesen Artikel ;).

    /**
     * Performs a wildcard matching for the text and pattern 
     * provided.
     * 
     * @param text the text to be tested for matches.
     * 
     * @param pattern the pattern to be matched for.
     * This can contain the wildcard character '*' (asterisk).
     * 
     * @return <tt>true</tt> if a match is found, <tt>false</tt> 
     * otherwise.
     */
    public static boolean wildCardMatch(String text, String pattern)
    {
        // Create the cards by splitting using a RegEx. If more speed 
        // is desired, a simpler character based splitting can be done.
        String [] cards = pattern.split("\\*");
 
        // Iterate over the cards.
        for (String card : cards)
        {
            int idx = text.indexOf(card);
 
            // Card not detected in the text.
            if(idx == -1)
            {
                return false;
            }
 
            // Move ahead, towards the right of the text.
            text = text.substring(idx + card.length());
        }
 
        return true;
    }

#ifdef in Java

Jeder, der C oder C++ kennt, kennt auch die Precompiler-Befehle. Mit #ifdef kann ein Entwickler den Compiler dazu veranlassen, bestimmte Codeabschnitte gar nicht mit zu kompilieren. Zum Beispiel, um Debug-Informationen aus dem endgültigen Code herauszufiltern bzw. diese nur bei Bedarf zu aktivieren.

In Java gibt es keine Precompiler. Man kann aber mit einem einfachen Mittel die Funktionalität von #ifdef nachbauen. Durch diesen Nachbau wird der Java-Compiler dazu gezwungen, bestimmte Codeabschnitte nicht mit in den Bytecode zu übernehmen.

public class AClass {
 
    public static final boolean COMP_CONDITION = true; 
 
    public static void main (String args[]) {
 
        // If  COMP_CONDITION is false, the compiler will ignore the entire if-statement.
        if (COMP_CONDITION) {
            System.out.println ("Running on true condition");
       }
 
    }
 
}

Durch die Deklarierung als statische finale Variable, weiß der Compiler, dass sich diese Variable auf keinen Fall mehr ändern kann, daher schmeißt er die if-Bedingung automatisch weg (falls false) und kompiliert sie nicht mit. Ansonsten wird die Bedingung ganz normal übernommen.

Auf diesem Wege kann man ein #ifdef aus C in Java nachbauen. Eine mögliche Alternative dazu ist evtl. auch AOP (JBoss AOP, AspectJ).

Schnelle Map/Set/List Initialisierung mit der “Double Brace Initialization”

Oft möchte man in Java eine HashMap anlegen und diese direkt auch mit Werten füllen. Mit normalen Methoden ist das so nicht möglich. Benötigt man die Map (Set, Liste, Array …) nur temporär muss man immer unschön mit add() neue Werte hinzufügen:

Set validCodes = new HashSet();
 
validCodes.add("aaa");
validCodes.add("bbb");
validCodes.add("ccc");
 
removeProductsWithCodeIn(validCodes);

Das erzeugt schlecht lesbaren Code und außerdem auch Overhead. Schöner wäre es, wenn man das Set gleich mit den Werten während der Initialisierung füllen könnte.

Das kann man seit Java 1.5 schon wie folgt erledigen, mit der “Double Brace Initialization”, also der Doppelklammer Initialisierung:

removeProductsWithCodeIn(new HashSet() {{
	add("aaa");
	add("bbb");
	add("ccc");
}});

Dies erzeugt genau das gleiche Resultat wie oben, vermeidet aber unnötige Codezeilen.

Was genau passiert dort nun? Also die ersten {} erzeugen eine neue anonyme innere Klasse (AnonymousInnerClass), die zweiten {} innerhalb der jetzt erzeugten anonymen inneren Klasse erzeugen einen sogenannten “instance initializer block”, also einen Block, der beim instanziieren der Klasse initialisiert wird. Klingt kompliziert, heißt aber nur, das was dort steht wird dann ausgeführt. Da eine innere Klasse erzeugt wird, klappt dieses Vorgehen nur bei nicht finalen Klassen (non-final).

Diese Methode ist nicht auf Collections beschränkt, sie funktioniert auch mit Objekten:

add(new JPanel() {{
	setLayout(...);
	setBorder(...);
	add(new JLabel(...));
}});

Ein einziges Problem gibt es allerdings, eine equals() Methode die wie folgt implementiert ist, greift nicht mehr korrekt:

public boolean equals(final Object o) {
	if (o == null) {
		return false;
	} else if (!getClass().equals(o.getClass())) {
		return false;
	} else {
		Example other = (Example) o;
		// Compare this to other.
	}
}

Warum? Ganz einfach, die neue erzeugte anonyme innere Klasse ist ja eine neue Klasse und damit nicht mehr gleich zur alten äußeren Klassen. Hier muss man also etwas aufpassen!

(via)

Design Pattern by Gamma und Co.

Jeder gute Programmierer sollte die grundlegenen Design Pattern von Gamma und Co. kennen. Für eine kleine 2-seitige Übersicht ist jetzt mit den Design Pattern Cards gesorgt.

Solche Pattern (Muster) helfen Probleme schnell und sauber zu lösen. Man kann sich damit sicher sein, eine gute Lösung zu nutzen und greift auf die langjährige Erfahrung einer ganzen Community zurück. Also, jeder sollte 5-10 Pattern kennen und auch anwenden können, ihr haltet damit euren Code wesentlich sauberer und besser wartbar!