Основные преимущества состоят в том, что можно создать уникальный идентификатор, не соединяясь с базой данных. И идентификатор глобально уникален, таким образом, можно легко объединить данные из различных баз данных. Они походят на небольшие преимущества, но сохранили меня большая работа в прошлом.
основные недостатки являются немного большим количеством необходимого устройства хранения данных (не проблема в современных системах), и идентификатор не действительно человекочитаемы. Это может быть проблемой при отладке.
существуют некоторые проблемы производительности как индексная фрагментация. Но те легко разрешимы (гуиды расчески jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862 )
Редактирование объединило мои два ответа на этот вопрос
@Matt Sheppard, я думаю, что он подразумевает, что Вы можете дублирующиеся строки с различными GUID как первичные ключи. Это - проблема с любым видом суррогатного ключа, не просто GUID. И как он сказал, что это легко решено путем добавления многозначительных ограничений на уникальность данных к нестолбцам ключа. Альтернатива должна использовать естественный ключ, и у тех есть настоящие проблемы..
Если вы знаете, что ваша строка всегда будет выглядеть так, попробуйте что-нибудь вроде:
HashMap map = new HashMap();
public void parse(String foo) {
String foo2 = foo.substring(1, foo.length() - 1); // hack off braces
StringTokenizer st = new StringTokenizer(foo2, ",");
while (st.hasMoreTokens()) {
String thisToken = st.nextToken();
StringTokenizer st2 = new StringTokenizer(thisToken, "=");
map.put(st2.nextToken(), st2.nextToken());
}
}
String getValue(String key) {
return map.get(key).toString();
}
Предупреждение: я на самом деле не пробовал это; могут быть незначительные синтаксические ошибки, но логика должна быть правильной. Обратите внимание, что я также выполнил нулевую проверку ошибок, поэтому вы можете сделать то, что я сделал, более надежным.
The speediest, but ugliest answer I can think of is parsing it character by character using a state machine. It's very fast, but very specific and quite complex. The way I see it, you could have several states:
Example:
int length = foo.length();
int state = READY;
for (int i=0; i<length; ++i) {
switch (state) {
case READY:
//Skip commas and brackets
//Transition to the KEY state if you find a letter
break;
case KEY:
//Read until you hit a = then transition to the value state
//append each letter to a StringBuilder and track the name
//Store the name when you transition to the value state
break;
case VALUE:
//Read until you hit a , then transition to the ready state
//Remember to save the built-key and built-value somewhere
break;
}
}
In addition, you can implement this a lot faster using StringTokenizers (which are fast) or Regexs (which are slower). But overall, individual character parsing is most likely the fastest way.
If the string has many entries you might be better off parsing manually without a StringTokenizer to save some memory (in case you have to parse thousands of these strings, it's worth the extra code):
public static Map parse(String s) {
HashMap map = new HashMap();
s = s.substring(1, s.length() - 1).trim(); //get rid of the brackets
int kpos = 0; //the starting position of the key
int eqpos = s.indexOf('='); //the position of the key/value separator
boolean more = eqpos > 0;
while (more) {
int cmpos = s.indexOf(',', eqpos + 1); //position of the entry separator
String key = s.substring(kpos, eqpos).trim();
if (cmpos > 0) {
map.put(key, s.substring(eqpos + 1, cmpos).trim());
eqpos = s.indexOf('=', cmpos + 1);
more = eqpos > 0;
if (more) {
kpos = cmpos + 1;
}
} else {
map.put(key, s.substring(eqpos + 1).trim());
more = false;
}
}
return map;
}
I tested this code with these strings and it works fine:
{k1=v1}
{k1=v1, k2 = v2, k3= v3,k4 =v4}
{k1= v1,}
Written without testing:
String result = null;
int i = foo.indexOf(key+"=");
if (i != -1 && (foo.charAt(i-1) == '{' || foo.charAt(i-1) == ',')) {
int j = foo.indexOf(',', i);
if (j == -1) j = foo.length() - 1;
result = foo.substring(i+key.length()+1, j);
}
return result;
Yes, it's ugly :-)
Ну, при условии, что в значениях нет '=' или ',', самый простой (и убогий) метод:
int start = foo.indexOf(key+'=') + key.length() + 1;
int end = foo.indexOf(',',i) - 1;
if (end==-1) end = foo.indexOf('}',i) - 1;
return (start<end)?foo.substring(start,end):null;
Да, не рекомендуется :)
Добавление кода для проверки наличия ключа
в foo
предоставляется читателю в качестве упражнения: -)
String foo = "{k1=v1,k2=v2,...}";
String getValue(String key){
int offset = foo.indexOf(key+'=') + key.length() + 1;
return foo.substring(foo.indexOf('=', offset)+1,foo.indexOf(',', offset));
}