1. Java / Говнокод #14401

    +69

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    String response = HttpLoader.loadString(params[0]);
    Gson gson = new GsonBuilder().registerTypeAdapter(ArrayList.class,
        new JsonCollectionSerializer<ArrayList<MyClass>>()).
        create();
    
    ArrayList<MyClass> items_generic = new ArrayList<MyClass>() { };
    ArrayList<MyClass> items = gson.fromJson(response, items_generic.getClass().getGenericSuperclass());
    return items;
    
    
    public class JsonCollectionSerializer<E> implements
            JsonSerializer<Collection<E>>, JsonDeserializer<Collection<E>> {
    
        @SuppressWarnings("unchecked")
        public Collection<E> deserialize(JsonElement element, Type type,
                                         JsonDeserializationContext context) throws JsonParseException {
            JsonArray items = element.getAsJsonArray();
            ParameterizedType deserializationCollectionType = ((ParameterizedType) type);
            Type collectionItemType = deserializationCollectionType.getActualTypeArguments()[0];
            Collection<E> list = null;
    
            try {
                list = (Collection<E>) ((Class<?>) deserializationCollectionType.getRawType()).newInstance();
                for (JsonElement e : items) {
                    list.add((E) context.deserialize(e, collectionItemType));
                }
            } catch (InstantiationException e) {
                throw new JsonParseException(e);
            } catch (IllegalAccessException e) {
                throw new JsonParseException(e);
            }
    
            return list;
        }
    }

    Жабоблядство и шаблоны и генерики:
    Чтение из json в коллекцию с шаблонным параметризованным типом.

    Запостил: chtulhu, 23 Января 2014

    Комментарии (23) RSS

    • А Jackson умеет в дженерики безо всяких извращений.

      List<MyClass> list = new ObjectMapper().readValue(jsonString, new TypeReference<List<MyClass>> { });


      Кстати, использовать переменные конкретных типов коллекций - плохой стиль.
      Ответить
      • В object сливать нужно а потом парсить?
        Ответить
        • Не поняла вопрос.
          Ответить
          • >Кстати, использовать переменные конкретных типов коллекций - плохой стиль.

            предпочтительно сохранять коллекцию object нежели MyClass?

            почему?
            Ответить
            • @someone имеет в виду List<MyClass> хорошо, ArrayList<MyClass> - плохо.
              Ответить
              • в чем в жабе отличие?
                Ответить
                • List - интерфейс, ArrayList - реализация.
                  Для шарпеев:
                  List = IList
                  ArrayList = List
                  Ответить
                  • Ферштейн.

                    Но почему?
                    Ответить
                    • Думаю, видимо, чтобы поменять реализацию было проще.
                      Ответить
                      • А, что бы можно было любую конкретную коллекцию инициализировать. То есть в шарпе оптимальный вариант - IEnumerable. Спасибо за обьяснение
                        Ответить
                        • У IEnumerable разве Count() не за O(n) вычисляется?
                          Ответить
                          • Count - это не часть IEnumerable<>, это метод расширение
                            Да, за O(n), но из IEnumerable<> можно любую коллекцию инициализировать. Тем белее скорее всего нужна будет обработка линком, а он все равно в IEnumerable<> переводит
                            Ответить
                            • > Да, за O(n)
                              Нет.
                              Сперва проверяется тип, и если у него есть свойство Length или Count, то возвращается оно. И лишь если ничего такого нет, то происходит пробег по коллекции.
                              Ответить
                        • > оптимальный вариант - IEnumerable
                          Не всегда...

                          Имхо, оптимальный вариант - самый минималистичный интерфейс из тех, которые позволят адекватно решить задачу.

                          Т.е. если функции нужен произвольный доступ к элементам - не надо закастовывать List по самый IEnumerable, а потом внутри функции создавать временный список через ToList(). Лучше сразу передать IList.
                          Ответить
                          • >>Имхо, оптимальный вариант - самый минималистичный интерфейс из тех, которые позволят адекватно решить задачу.

                            я так и понял.
                            Ответить
      • 1) Gson это тоже умеет, только так new TypeToken<List<MyClass>>{}.getType()
        2) Не всегда, бывают, случаи, когда тебе важено иметь именно конкретный тип
        Ответить
    • А начиная с какой Явы можно писать:
      try { ... } catch (Foo | Bar e) { ... }

      Я как для себя это открыл, прям чуть не зарыдал от счастья.

      + Да, Джексон лучше Г.сона. Как там в плане скорости - хз. но по крайней мере своего говнокода к уже имеющемуся не нужно так много добавлять.
      Ответить
    • СТАТИКОПРОБЛЕМЫ. Кстати, а насколько проще это будет выглядеть в сишарпе с его dynamic?
      Ответить

    Добавить комментарий