Zahlen in String durch Namen ersetzen

Copia

Grünschnabel
Hallo zusammen,

ich habe foldendes Problem:

Ich habe einen String, der als Array aufgebaut ist, also so: {1000,2000,3000,...}
Dazu habe ich eine Map, die zu jeder Zahl einen entsprechenden Namen enthält, zB:
1000 - Haus
2000 - Baum
3000 - Tier

Jetzt möchte ich den String umwandeln, und zwar von {1000,2000,3000} in {Haus,Baum,Tier}.
Zudem soll jeder Eintrag nur einmal vorkommen. Das funktioniert auch alles, allerdings find ich das hässlich, wie ich das gelöst habe.

Hat jemand eine Idee, wie das eleganter zu lösen ist?

Code:
public class GroupFormattingModel extends FormattingTableModel {
        
        public static final SortedMap<String, Object> GROUPS = new TreeMap<String, Object>();
        static {
                GROUPS.put("1000", "Haus");
                GROUPS.put("1010", "Sonderartikel");
                GROUPS.put("1020", "Bestellwert");
        }
        
        public GroupFormattingModel () {
                super("GROUP");
        }
        
        private String groupNameToNumber(String group){
                String val = "";
                for(Map.Entry<String, Object> map : GROUPS.entrySet()){
                        if(map.getValue().equals(group)){
                                val = ""+map.getKey();
                                break;
                        }
                }
                return val;
        }
        
        private String groupNumberToName(String group){
                String val = (String)GROUPS.get(group);
                if(val == null) return "";
                return val;
        }
        
        public static List<String> groupStringAsList(String group){
                group = group.replaceAll("[\\{\\}]", "");
                List<String> groups = new ArrayList<String>(Arrays.asList(dgroup.split(",")));
                return groups;
        }
        
        public static String groupListAsString(List<String> groups){
                StringBuilder sb = new StringBuilder();
                boolean any = false;
                for(String s : groups){
                        if(any) sb.append(",");
                        sb.append(s);
                        any = true;
                }
                return sb.toString();
        }

        @Override
        protected String formatValueDownwards(String val) throws Exception {
                if(val.length() < 3) return "";
                
                List<String> groupsAsNames = groupStringAsList(val, ";");
                List<String> groupsAsNumbers = new ArrayList<String>();
                for(String s : groupsAsNames){
                        groupsAsNumbers.add(groupNameToNumber(s));
                }
                
                StringBuilder sb = new StringBuilder("{");
                sb.append(groupListAsString(groupsAsNumbers, ","));
                sb.append("}");
                return sb.toString();
        }

        @Override
        protected String formatValueUpwards(String val) throws Exception {
                if(val.length() < 3) return "";
                
                List<String> groupsAsNumbers = groupStringAsList(val, ",");
                List<String> groupsInNames = new ArrayList<String>();
                for(String s : groupsAsNumbers)
                        groupsInNames.add(groupNumberToName(s));
                
                StringBuilder sb = new StringBuilder("{");
                sb.append(groupListAsString(groupsInNames, ";"));
                sb.append("}");
                
                return sb.toString();
        }
}
 
Zuletzt bearbeitet:
Wenn du Wert darauf legst, dass Werte nur einmal vorkommen, solltest du ein Set bzw. HashSet verwenden.
Zum Zerteilen des Strings in Zahlen schau dir mal folgendes Beispiel an:
Java:
public class Test {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		test();
	}
	static void test()
	{
		String str = "{1000,2000,3000,4000}";
		String tmp;
		// Alles außerhalb der Klammern wird entfernt
		tmp = str.replaceAll(".*\\{","");
		tmp = tmp.replaceAll("\\}.*","");
		// String in einzelne Zahlenstrings zerteilen
		String[] num = tmp.split(",");
		int[] val = new int[num.length];
		// Zahlenstrings in int umwandeln
		int i = 0;
		for ( String s : num )
		{ val[i++] = new Integer(s); }
		// Testausgabe
		for ( int v : val )
		{ System.out.printf(">%d\n", v); }
	}
}
Durch das Autounboxing wird das Integer-Objekt automatisch in einen int-Wert umgewandelt.
 
Zuletzt bearbeitet:
Erstmal danke für die Antwort.

Mir ging es jedoch nicht darum, die Zahlen in ints umzuwandeln. Ich nutze die ja als String.
Mir geht es darum, eine elegante Lösung zu finden, einen solchen String: {1000,2000,3000} in solch einen: {Haus,Baum,Tier} zu übersetzen.
 
Moin

Mir geht es darum, eine elegante Lösung zu finden, einen solchen String: {1000,2000,3000} in solch einen: {Haus,Baum,Tier} zu übersetzen

Ich muss zugeben, dass ich Dein Problem nicht ganz verstehe, da Du doch schon eine Map benutzt, wie Du geschrieben hast :
Ich habe einen String, der als Array aufgebaut ist, also so: {1000,2000,3000,...}
Dazu habe ich eine Map, die zu jeder Zahl einen entsprechenden Namen enthält, zB:
1000 - Haus
2000 - Baum
3000 - Tier

Hierüber hast Du dann doch automatisch die entsprechende Zuordnung ..... :suspekt:
Was genau möchtest Du denn noch WO ersetzen :confused:

Gruß
Klaus
Klaus
 
Also in der Datenbank wird ein Array gespeichert, welches so aufgebaut ist: {1000,2000,3000,...}. Da dieses Array aber im Programm nicht in Zahlen, sondern in Wörtern angezeigt werden soll, wollte ich auf diesem Weg die Zahlen in Wörter umwandeln.
Um dann die Wörter aber wieder in der Datenbank zu speichern, müssen diese wieder in das Zahlenformat umgewandelt werden. Die Übersetzungen finden in einem Tabellenmodell statt, dass zwischen Datenbank und GUI liegt.

Wenn ihr dafür einen ganz anderen Ansatz habt, gerne her damit ;-)
 
Kleine Zwischenfrage: Wieso verwendest Du bei der Map <String, Object> und nicht <Integer, String> ?
Und die Zahlen in der Datenbank repraesentieren ein Wort? Wieso hast Du in der Datenbank keine Tabelle mit den Woertern die dann durch eine ID identifiziert werden? Ich muss zugeben mir erschliesst sich das Ganze irgendwie nicht.
 
DIe Zahlen in der Datenbank sind ein Array, also ein integer[ ].
Zur Zwischenfrage: Die Typisierung hab ich schon geändert.
 
Hallo,

um den von Dir gesendeten Code zu analysieren fehlt mir die Zeit. Mir scheint er einerseits professionell und richtig
zu sein, andererseits hätte mir auch eine Ausführungsreihenfolge geholfen.

Ich finde, dass Vereth schon nützliche tipps gegeben hat, indem er z.B. die split()-Methode von String eingesetzt hat.

mögliches Vorgehen:
split() erkennt die Zeichenketten (Strings) die zwischen den Kommata (oder sonstigen genutzten Zeichen) stehen
und lagert(speichert die der Reihe nach in ein Array von Strings namens arrStr1.

Die einzelnen Elemente dieses Array arrStr1 müssen nun einzelnen gelesen werden und z.B per switch Anweisung kann dann jedes Element, entsprechend Deiner key-value Map,getestet werden und in den entsprechenden String übersetzt werden.
Hier kannst Du mit den einschlägigen String Methoden [z.B. concat(), substring, replace(),trim() etc. ] einen neuen (den übersetzten) Ergebnisstring aufbauen. Wenn dieser dann mit { anfängt die Namen z.B Haus etc. jeweils mit Komma trennt
und mit "}" aufhört, dann ist das doch das was Du wolltest.
Oder?

Gruß
Steve222
 
Hallo,

die split-Methode nutze ich ja. Ich trenne die einzelnen Elemente dadurch, ersetze sie anhand der Map und füge sie mit dem StringBuilder wieder zusammen. Es tut ja auch das, was ich will. Ich bin nur leider nicht so erfahren und dachte mir, dass mein Code "gefrickelt" ist. Deswegen wollte ich mir Tipps holen, wie man das evtl. "schöner" machen kann.

Trotzdem danke für eure Tipps!
 
Du scheinst auf diese ein wenig unbeholfen wirkende Art eine m:n-Relation in deiner Datenbank darstellen zu wollen; das wäre dann nicht nur etwas umständlich, sondern auch ineffizient. Vorbeugenderweise möchte ich dir deshalb erklären, wie so etwas richtig gemacht wird.
Nehmen wir an, du möchtest Personen Adressen zuordnen und umgekehrt; eine Person kann mehrere Adressen haben, und an einer Adresse können mehrere Personen wohnen; der Einfachheit halber beschränke ich mich auf Orte.
Alice, Bob und Charlie sind Kollegen in einer Firma in Ahaus und haben dort deswegen auch eine Wohnung. Alice besucht am Wochenende immer ihre Eltern in Berlin; Bob und Charlie haben sich zusammen eine Ferienwohnung in Chur zugelegt. Wir haben also zwei Tabellen 'Ort' und 'Person' mit folgenden Einträgen:
Code:
Ort               Person
------------      ------------
1 | Ahaus         A | Alice
2 | Berlin        B | Bob
3 | Chur          C | Charlie
Die erste Spalte ist jeweils die Id des Datensatzes und dient als eindeutiger Schlüssel.
Wir haben nun eine m:n-Relation zwischen den Tabellen 'Ort' und Person; um diese darzustellen, verwenden wir eine Assoziationstabelle, die wir 'dazwischenlegen'. Diese Tabelle nennen wir 'OrtZuPerson', und sie hat nur zwei Spalten: eine für den Schlüsselwert des Ortes(1-3), und eine für den Schlüsselwert der Person(A-C). Jeder dieser Schüsselwerte kann mehrmals vorkommen, aber jede Kombination nur einmal. Deswegen können wir einen eindeutigen Schlüssel definieren, der aus den beiden Spalten 'Ort_Id' und 'Person_Id' zusammengesetzt ist. Am besten definieren wir sogar zwei, für jede Möglichkeit der Darstellungsweise einen ('Ort_Id','Person_Id' und 'Person_Id','Ort_Id'). Diese Tabelle hat dann in unserem Beispiel folgende Einträge:
Code:
OrtZuPerson
-----------
1 | A // die drei Adressen in Ahaus
1 | B
1 | C 
2 | A // die Berliner Adresse von Alice
3 | B // Bobs Adresse in seiner Ferienwohnung
3 | C // Charlies Adresse für seine Ferienwohnung
Wenn du nun die Adresse/n einer Person herausfinden möchtest, suchst du zuerst in der Tabelle 'Person' deren Id heraus, ermittelst dann in der Tabelle 'OrtZuPerson', welche Einträge dort vorhanden sind, und schaust dann in der Tabelle 'Ort', welche Adressen den gefundenen 'Ort_Id's zugeordnet sind; all dies kann mit Hilfe eines einzigen SELECT-Statements gemacht werden. Wenn du den umgekehrten Fall hast, verfährst du entsprechend.
Ich hoffe, dir damit weitergeholfen zu haben, und wünsche dir viel Erfolg bei der Anwendung.
 
Zuletzt bearbeitet:
Zurück