2 Stimmen

Herangehensweise: Java-Array mit Instanzen von zwei verschiedenen Klassen

Ich versuche, eine einfache Regex Art von Sache für meinen eigenen Gebrauch zu erstellen, wo ein Zeichen in einer Zeichenfolge kann entweder eine genaue Übereinstimmung oder ein in einer Menge von Zeichen, die zu einer Gruppe (z. B. Gruppe CAPS haben alle Großbuchstaben - 'A', 'B', etc.). Daher ist eine Regex wie - CAPS p p l e - sollte mit 'Apple' oder einem Regex wie - DIGIT DIGIT . DIGIT - sollte 76,3 entsprechen.

Ich versuche, dieses Regex-Muster in einem Array zu speichern {CAPS, 'p', 'p', 'l', 'e'} . In Java kann ich nun ein Array vom Typ char[]/Character[] o Group[] wobei Gruppe eine von mir konstruierte Klasse ist, die solche Gruppen von Zeichen darstellt. Wenn ich ein hybrides Array benötige, um die oben erwähnten Muster zu speichern, welche anderen Optionen habe ich, außer ein Array vom Typ Object[] ?

Ich möchte wirklich nicht mit einem Array des Typs Object[] .

3voto

Péter Török Punkte 111735

Man könnte eine gemeinsame Oberklasse (Schnittstelle) definieren, mit Unterklassen sowohl für normale Zeichen als auch für Zeichenklassen/-gruppen.

1voto

whaley Punkte 15747

Wenn Sie ein hybrides Array oder eine Sammlung wünschen, müssen Sie char/Character und Group hinter einer gemeinsamen Schnittstelle oder einem Supertyp abstrahieren. Da char ein Primitivum und Character eine finale Klasse ist, ist es am besten, eine Schnittstelle zu schreiben und char/Character zu umhüllen.

Ich würde vorschlagen, Group zu einer Schnittstelle zu machen (eventuell umzubenennen) und dann zwei Klassen zu erstellen, die Group implementieren - eine, die ein Char oder Character umhüllt (nennen wir sie SingleChar), und eine konkrete Group (nennen wir sie vorerst GroupImpl), die den Zweck der ursprünglichen Group erfüllt. Erstellen Sie ein Array von Group[] und manipulieren Sie jede Instanz von Group über Ihre gemeinsame Schnittstelle.

0voto

leonbloy Punkte 68836

Es ist nicht möglich, ein Array mit Elementen aus einem von zwei nicht miteinander verbundenen Typen zu definieren.

Sie können einen eigenen Supertyp (oder eine Schnittstelle) definieren, von dem aus Sie zwei Klassen erweitern, von denen eine ein Zeichen und die andere Ihre Gruppe umschließt.

Oder, vielleicht einfacher, verwendet einfach ein Object[] und wickeln, dass mit einer Klasse, die die Intelligenz zu setzen / erhalten die richtigen Typen hat.

0voto

Bill K Punkte 61074

Char[] ist nicht typisiert und vielleicht nicht das Beste, um damit zu interagieren.

Group[] ist nicht wirklich sehr beschreibend für das, was es tut.

Vielleicht könnte man eine Schnittstelle mit der Methode "match" einrichten und dort eine Reihe von Objekten einfügen, die diese Schnittstelle implementieren.

So könnte eines dieser Objekte als "new MatchChar('a')" instanziiert werden, während ein anderes "new MatchType(MatchType.CAPS)" sein könnte.

Das Problem dabei ist, dass es nicht sehr einfach zu instanziieren ist - es ist sehr umfangreich. Ich würde eine Methode (sagen wir innerhalb von "Match", die eine Oberklasse von MatchType und MatchChar sein könnte) wie getMatches verwenden, die eine Zeichenkette nehmen und Ihr Array zurückgeben würde, vollständig generiert.

Mir gefällt, dass Ihre "Sprache" im Allgemeinen expliziter ist als Regex, wie wäre es also mit etwas wie diesem: "[DIGIT][DIGIT].[DIGIT]" oder "[CAPS]pple"--zudem die obligatorischen "[[]" und "[]]", um Klammern anzupassen.

Dann sucht Ihre Methode einfach nach übereinstimmenden [] in der Zeichenfolge, erstellt die richtigen MatchGroup-Objekte, wandelt die verbleibenden Buchstaben in MatchChar-Objekte um und gibt sie an den Aufrufer zurück.

Das Parsen einer solchen Zeichenkette ist ziemlich einfach, der StringTokenizer hätte seine helle Freude daran.

0voto

samitgaur Punkte 5441

Sie können die Verbundwerkstoff Entwurfsmuster, um diese Situation zu modellieren. Dieses Muster ist nützlich, wenn Sie einen Objekttyp und die Sammlung von Objekten dieses Typs auf dieselbe Weise behandeln müssen. Sie können auch Kette der Verantwortung Muster mit sich.

Grundsätzlich würden Sie Klassen wie folgt definieren (sagen wir, Sie benötigen eine matches()-Methode):

class Pattern {
    IPatternComponent[] pattern;
    boolean matches(String str) {
        for(int i = 0; i < str.length; i++) {
            if(!pattern[i].matches(str.charAt(i)))
                return false;
        }
        return true;
    }
}

interface IPatternComponent {
    boolean matches(char ch);
}

class Simple implements IPatternComponent {
    char ch;
    boolean matches(char ch) {
        return (this.ch == ch);
    }
}

class Group implements IPatternComponent {
    Set<IPatternComponent> components;
    boolean matches(char charToMatch) {
        for(IPatternComponent comp : components) {
            if(comp.matches(charToMatch)
                return true;
        }
        return false;
    }
}

Die Einnahme der DIGIT DIGIT . DIGIT Beispiel:

  • Das gesamte Muster wird dargestellt durch eine Instanz von Pattern Klasse.
  • Die Instanz speichert die einzelnen Teile in ihrem internen Array- { DIGIT , DIGIT , . , DIGIT }.
  • . wird eine Instanz von Simple .
  • DIGIT wird eine Instanz von Group die Folgendes speichern wird 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 in seinem internen set
  • Jedes Element der Menge wird durch eine Instanz von Simple .
  • matches() wird mit der Kette funktionieren Verantwortungskette - Delegieren der Verantwortung nach unten in der Kette.

Mit diesem Design können Sie auch leicht definieren ALPHANUM als Group deren interne Menge aus folgenden Elementen besteht ALPHABETS y DIGIT y matches() funktioniert trotzdem.

Hinweis: Ich habe den Code hier direkt codiert, daher kann er Tippfehler oder kleine Fehler enthalten. Zur besseren Lesbarkeit habe ich die Konstruktoren weggelassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X