regex нечувствительность к регистру медленнее?

1) Вам нужно создать пользовательские JsonDeserializer, а не JsonSerializer, как в вашем вопросе.

2) Я не думаю, что это поведение происходит из Double десериализатора. это больше похоже на проблему json object / map

. Из исходного кода :

case NUMBER:
      return in.nextDouble();

Итак, вы можете попробовать подход с настраиваемым десериализатором для Map (или, если хотите, какую-нибудь более общую карту):

public static class MapDeserializerDoubleAsIntFix implements JsonDeserializer>{

    @Override  @SuppressWarnings("unchecked")
    public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return (Map) read(json);
    }

    public Object read(JsonElement in) {

        if(in.isJsonArray()){
            List list = new ArrayList();
            JsonArray arr = in.getAsJsonArray();
            for (JsonElement anArr : arr) {
                list.add(read(anArr));
            }
            return list;
        }else if(in.isJsonObject()){
            Map map = new LinkedTreeMap();
            JsonObject obj = in.getAsJsonObject();
            Set> entitySet = obj.entrySet();
            for(Map.Entry entry: entitySet){
                map.put(entry.getKey(), read(entry.getValue()));
            }
            return map;
        }else if( in.isJsonPrimitive()){
            JsonPrimitive prim = in.getAsJsonPrimitive();
            if(prim.isBoolean()){
                return prim.getAsBoolean();
            }else if(prim.isString()){
                return prim.getAsString();
            }else if(prim.isNumber()){
                Number num = prim.getAsNumber();
                // here you can handle double int/long values
                // and return any type you want
                // this solution will transform 3.0 float to long values
                if(Math.ceil(num.doubleValue())  == num.longValue())
                   return num.longValue();
                else{
                    return num.doubleValue();
                }
            }
        }
        return null;
    }
}

Чтобы использовать ее, вам нужно будет отдать TypeToken функции registerTypeAdapter и gson.fromJson:

String json="[{\"id\":1,\"quantity\":2,\"name\":\"apple\"}, {\"id\":3,\"quantity\":4,\"name\":\"orange\"}]";

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(new TypeToken>(){}.getType(),  new MapDeserializerDoubleAsIntFix());

Gson gson = gsonBuilder.create();
List> l = gson.fromJson(json, new TypeToken>>(){}.getType() );

for(Map item : l)
    System.out.println(item);

String serialized = gson.toJson(l);
System.out.println(serialized);

Результат:

{id=1, quantity=2, name=apple}
{id=3, quantity=4, name=orange}
Serialized back to: [{"id":1,"quantity":2,"name":"apple"},{"id":3,"quantity":4,"name":"orange"}]

PS: Это еще один вариант, который вы можете попробовать. Лично я чувствую, что создание пользовательского объекта для вашего json вместо List> намного более круто и проще для чтения

14
задан Commercial Suicide 20 September 2017 в 21:16
поделиться

3 ответа

Да, [A-Za-z] будет намного быстрее, чем установка эти RegexOptions.IgnoreCase, в основном из-за строк Unicode. Но это также намного больше ограничивает - [A-Za-z], делает не , соответствие акцентировало международные символы, это - буквально набор ASCII A-Za-z и ничто больше.

я не знаю, видели ли Вы ответ Tim Bray на мое сообщение, но это - хорошее:

Одной из самых хитрых проблем в интернационализировавшем поиске является верхний регистр и нижний регистр. Это понятие случая ограничено языками, записанными на латинском, греческом и наборах символа кириллицы. Носители английского языка естественно ожидают, что поиск будет нечувствителен к регистру если только потому, что they’re ленивый: если Nadia Jones хочет искать себя на Google she’ll, вероятно, просто вводят в nadia Джонсе и ожидают, что система будет заботиться о нем.

Так it’s довольно характерный для поисковых систем к “normalize” словам путем преобразования их всех для понижения - или верхний регистр, и для индексации и для запросов.

проблема состоит в том, что отображение между случаями не всегда так же просто, как это находится на английском языке. Например, немецкий символ нижнего регистра “ß” становится “SS”, когда верхний в корпусе и старым добрым капиталом, “I”, когда вниз в корпусе на турецком языке становится “ı” без точки (да, у них есть “i”, его прописная версия является “İ”). Я считал (но не проверил непосредственно), что правила для upcasing символов с диакритикой такой “é” отличаются во Франции и QuГ©bec. Один из результатов всего этого то, что программное обеспечение, такое как Java. String.toLowerCase () имеет тенденцию работать удивительно медленный, поскольку он пытается работать вокруг всех этих угловых случаев.

http://www.tbray.org/ongoing/When/200x/2003/10/11/SearchI18n

17
ответ дан 1 December 2019 в 13:34
поделиться

Если Вы обеспокоены этим, может стоить установить случай на всех верхних, или все понижаются перед проверкой.
, Например, в Perl:

$x = "abbCCDGBAdgfabv";
(lc $x) =~ /bad/;

май в некоторых случаях быть лучше, чем

$x = "abbCCDGBAdgfabv";
$x =~ /bad/i;
0
ответ дан 1 December 2019 в 13:34
поделиться

Если можно терпеть числа наличия и подчеркивания в этом regex, Вы можете, например, использовать \w модификатор (синтаксис Perl). Я верю некоторой поддержке механизмов [: альфа:], но это не чистый Perl. \w принимает во внимание локаль, в которой Вы находитесь, и соответствует и верхнему регистру и нижнему регистру, и я держал пари, что это быстрее, чем использование [A-Z] при игнорировании регистра.

1
ответ дан 1 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: