Извлечь список String из RealmResult [duplicate]

В других словах

  • document.querySelector() выбирает только первый элемент указанного селектора. Поэтому он не выплевывает массив, это одно значение. Подобно document.getElementById(), который извлекает только ID-элементы, поскольку идентификаторы должны быть уникальными.
  • document.querySelectorAll() выбирает все элементы с указанным селектором и возвращает их в массиве. Похоже на document.getElementsByClassName() только для классов и document.getElementsByTagName().

Зачем использовать querySelector?

Используется просто для единственной цели легкость и краткость.

Зачем использовать getElement / sBy? *

Более быстрая производительность.

Почему это различие в производительности?

Оба способа выбора имеют целью создание NodeList для дальнейшего использования. querySelectors генерирует статический NodeList с селекторами, поэтому он должен быть сначала создан с нуля. getElement / sBy * немедленно адаптирует существующий живой NodeList текущего DOM.

Итак, когда использовать какой метод зависит от вас / вашего проекта / вашего устройства.

Infos

Демонстрация всех методов Документация NodeList Тест производительности

28
задан mgamer 26 April 2012 в 11:09
поделиться

7 ответов

EDIT: этот ответ основан на идее, что вам нужно будет делать подобные вещи для разных объектов и разных свойств в другом месте вашего кода. Если вы только должны преобразовать список ViewValues ​​в список Longs by ID, тогда придерживайтесь своего исходного кода. Однако, если вы хотите использовать более многоразовое решение, прочитайте ...

Я бы объявил интерфейс для проекции, например

public interface Function<Arg,Result>
{
    public Result apply(Arg arg);
}

. Тогда вы можете написать одно общее преобразование method:

public <Source, Result> List<Result> convertAll(List<Source> source,
    Function<Source, Result> projection)
{
    ArrayList<Result> results = new ArrayList<Result>();
    for (Source element : source)
    {
         results.add(projection.apply(element));
    }
    return results;
}

Тогда вы можете определить простые проекции, подобные этому:

private static final Function<ViewValue, Long> ID_PROJECTION =
    new Function<ViewValue, Long>()
    {
        public Long apply(ViewValue x)
        {
            return x.getId();
        }
    };

И примените его так:

List<Long> ids = convertAll(values, ID_PROJECTION);

(Очевидно с помощью кнопок K & amp; R и более длинных строк упрощает объявление прокрутки:)

Честно говоря, все это было бы намного лучше с лямбда-выражениями, но неважно ...

24
ответ дан Jon Skeet 23 August 2018 в 02:32
поделиться
  • 1
    Очень Javaesque решение - но не в хорошем смысле. Это точно не уменьшает количество или сложность кода, не так ли? – Michael Borgwardt 10 April 2009 в 11:35
  • 2
    Я бы сказал, что это больше LINQ-esque, чем Java-esque. Я бы предпочел создать код преобразования, а затем изолировать проекционный аспект, но если вы предпочтете дублировать логику конверсии раз, это нормально. Конечно, было бы намного лучше с лямбда-выражениями. – Jon Skeet 10 April 2009 в 11:44
  • 3
    Разве это не так, как мы с компаратором в Java? – Adeel Ansari 10 April 2009 в 11:47
  • 4
    На самом деле это не только то, что я помню. Однако я обратился к этому с идеей повторного использования, которое может не потребоваться - редактирование моего ответа, чтобы отразить это. – Jon Skeet 10 April 2009 в 11:49
  • 5
    (Обратите внимание, что мой комментарий «много раз» предполагал, что это потребуется для разных свойств и т. Д., А не только для одного.) – Jon Skeet 10 April 2009 в 12:06

Мы можем сделать это в одной строке кода, используя java 8

List<Long> ids = viewValues.stream().map(ViewValue::getId).collect(Collectors.toList());

. Для получения дополнительной информации: Java 8 - Потоки

21
ответ дан Jad Chahine 23 August 2018 в 02:32
поделиться
  • 1
    К счастью, мы все упрощаем, когда разрабатываем :) – Radhakrishna Sharma Gorenta 10 June 2016 в 11:23
  • 2
    Хорошо, позвольте мне сказать прямо: я бы добавил комментарии, что это включено с Java8, который не был доступен на момент написания. Ответ на самом деле большой шаг вперед к тому, что было написано 7 лет назад. – Alex 10 June 2016 в 12:21

Я реализовал небольшую функциональную библиотеку для этой утилиты. Один из методов имеет эту подпись:

<T> List<T> mapToProperty(List<?> objectList, String property, Class<T> returnType)

Что берет строку и использует отражение для создания вызова свойства, а затем возвращает список, поддерживаемый objectList, где get и iterator реализованы с использованием этого вызова свойства .

Функции mapToProperty реализованы в терминах общей функции карты, которая принимает функцию как средство отображения, хотя, как описано в другой статье. Очень полезно.

Предлагаю вам ознакомиться с базовым программированием функций и, в частности, взглянуть на функторы (объекты, реализующие функцию карты)

Редактировать: отражению действительно не нужно быть дорогим. В этой области JVM значительно улучшилась. Просто убедитесь, что один раз скомпилировали вызов и повторно его использовали.

Edit2: Пример кода

public class MapExample {
    public static interface Function<A,R>
    {
        public R apply(A b);
    }

    public static <A,R> Function<A,R> compilePropertyMapper(Class<A> objectType, String property, Class<R> propertyType)
    {
        try {
            final Method m = objectType.getMethod("get" + property.substring(0,1).toUpperCase() + property.substring(1));

            if(!propertyType.isAssignableFrom(m.getReturnType()))
                throw new IllegalArgumentException(
                    "Property "+property+" on class "+objectType.getSimpleName()+" is not a "+propertyType.getSimpleName()
                );

            return new Function<A,R>() 
            {
                @SuppressWarnings("unchecked")
                public R apply(A b)
                {
                    try {
                        return (R)m.invoke(b);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                };
            };

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T1,T2> List<T2> map(final List<T1> list, final Function<T1,T2> mapper)
    {
        return new AbstractList<T2>()
        {
            @Override
            public T2 get(int index) {
                return mapper.apply(list.get(index));
            }

            @Override
            public int size() {
                return list.size();
            }
        };
    }

    @SuppressWarnings("unchecked")
    public static <T1,T2> List<T2> mapToProperty(List<T1> list, String property, Class<T2> propertyType)
    {
        if(list == null)
            return null;
        else if(list.isEmpty())
            return Collections.emptyList();

        return map(list,compilePropertyMapper((Class<T1>)list.get(0).getClass(), property, propertyType));
    }
}
4
ответ дан John Nilsson 23 August 2018 в 02:32
поделиться

Вы могли бы обмануть оболочку:

public class IdList impements List<Long>
{
    private List<ViewValue> underlying;

    pubic IdList(List<ViewValue> underying)
    {
        this.underlying = underying;
    }

    public Long get(int index)
    {
        return underlying.get(index).getId()
    }

    // other List methods
}

, хотя это еще более утомительная работа, это может повысить производительность.

Вы также можете реализовать свое и мое решение с помощью отражения, но это будет очень плохо для успеха.

Theres не краткое и простое универсальное решение на Java, я боюсь. В Groovy вы просто используете collect (), но я считаю, что это также связано с отражением.

3
ответ дан Michael Borgwardt 23 August 2018 в 02:32
поделиться

Используйте коллекцию google. Пример:

    Function<ViewValue, Long> transform = new Function<ViewValue, Long>() {
        @Override
        public Long apply(ViewValue from) {
            return from.getId();
        }
    };
    List<ViewValue> list = Lists.newArrayList();
    List<Long> idsList = Lists.transform(list, transform);

UPDATE:

На Java 8 вам не нужен Guava. Вы можете:

import com.example.ViewValue;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

Function<ViewValue, Long> transform = ViewValue::getId;
List<ViewValue> source = new ArrayList<>();
List<Long> result = source.stream().map(transform).collect(Collectors.toList());

Или просто:

List<ViewValue> source= new ArrayList<>();
List<Long> result = source.stream().map(ViewValue::getId).collect(Collectors.toList());

СЛЕДУЮЩЕЕ ОБНОВЛЕНИЕ (последнее после изменения Javaslang на Vavr):

В настоящее время это стоит упомянуть о решении с библиотекой Javaslang ( http://www.javaslang.io/ ) библиотека Vavr ( http://www.vavr.io/ ). Предположим, что у нас есть наш список с подлинными объектами:

List<ViewValue> source = newArrayList(new ViewValue(1), new ViewValue(2), new ViewValue(2));

Мы могли бы сделать преобразование с помощью класса List из библиотеки Javaslang (в конечном счете сбор не удобен):

List<Long> result = io.vavr.collection.List.ofAll(source).map(ViewValue::getId).toJavaList();

Но вы увидите власть только с списками Javaslang:

io.vavr.collection.List<ViewValue> source = javaslang.collection.List.of(new ViewValue(1), new ViewValue(2), new ViewValue(3));
io.vavr.collection.List<Long> res = source.map(ViewValue::getId);

Я рекомендую посмотреть доступные коллекции и новые типы в этой библиотеке (особенно мне нравится тип Try). Вы найдете документацию по следующему адресу: http://www.javaslang.io/javaslang-docs/ http://www.vavr.io/vavr-docs/ .

PS. Из-за Oracle и слова «Java» в названии им пришлось изменить имя библиотеки из javaslang на что-то еще. Они решили Вавра.

28
ответ дан Przemek Nowak 23 August 2018 в 02:32
поделиться

Это зависит от того, что вы делаете с List<Long> и List<ViewValue>

. Например, вы можете получить достаточную функциональность от создания собственной реализации списка, которая обертывает List<ViewValue>, реализуя iterator() с реализацией итератора, которая выполняет итерацию над ViewValues, возвращая идентификатор.

2
ответ дан Stephen Denne 23 August 2018 в 02:32
поделиться

Вы можете сделать это в однострочном пространстве, используя Commons BeanUtils и Collections: (зачем писать свой собственный код, когда другие сделали это для вас?)

import org.apache.commons.beanutils.BeanToPropertyValueTransformer;
import org.apache.commons.collections.CollectionUtils;

...

List<Long> ids = (List<Long>) CollectionUtils.collect(viewValues, 
                                       new BeanToPropertyValueTransformer("id"));
32
ответ дан Ulf Lindback 23 August 2018 в 02:32
поделиться
  • 1
    +1 для комментария "зачем писать свой собственный код, когда другие сделали это для вас? & Quot; Это проблема, с которой мы сталкиваемся ежедневно - нужно создать решение проблемы, которая уже решена. – divesh premdeep 7 August 2012 в 08:02
  • 2
    PropertyUtils.getProperty (object, propertyName); использует отражение под капотом, которое будет иметь дополнительную производительность. Для этого я бы использовал подход Джона Скита. – Juan Carlos Blanco Martínez 16 October 2013 в 12:52
  • 3
    Единственное, что мне не нравится в этом, - это отсутствие безопасности типа - если поле viewValue.id было переименовано, код все равно будет компилироваться, но сбой во время выполнения. – Steve Chambers 8 November 2016 в 11:30
Другие вопросы по тегам:

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