Как получить доступ к атрибуту объекта из строки в Java?

У меня есть строка, которая сообщает мне, какой атрибут я должен использовать для некоторой фильтрации. Как я могу использовать эту строку для фактического доступа к данным в объекте?

У меня есть метод, который возвращает список строк, говорящих мне, как фильтровать мой список объектов. Такие как:

String[] { "id=123", "name=foo" }

Итак, моя первая идея состояла в том, чтобы разделить строку на 2 части с помощью: filterString.split(" = ") и используйте первую часть строки (например, «id») для идентификации фильтруемого атрибута.

Что касается фона JS, я бы сделал это так:

const attr = filterString.split('=')[0]; // grabs the "id" part from the string "id=123", for example
const filteredValue = filterString.split('=')[1]; // grabs the "123" part from the string "id=123", for example
items.filter(el => el[`${attr}`] === filteredValue) // returns an array with the items where the id == "123"

Как бы я мог сделать это с Java?

Java — строго типизированный язык, поэтому определение item теперь актуально. Другими словами, укажите класс, который вы собираетесь использовать для списка/массива items.

Izruo 07.06.2019 19:27

Что ты пытаешься сделать? Проверить сериализацию/десериализацию

Xavier Bouclet 07.06.2019 19:28

Это очень динамично для Java. Если переменные el в вашем фрагменте JS являются Map в Java, то это возможно, поскольку attr будет сопоставляться с ключами, но если предполагается, что attr соответствует именам свойств класса, я вижу только отражение, которое нужно использовать , что я обычно не рекомендую, кроме как в крайнем случае.

sp00m 07.06.2019 19:29
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
1 504
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Этот код должен работать:

  //create the filter map
  Map<String, String> expectedFieldValueMap = new HashMap<>();
    for (String currentDataValue : input) {
        String[] keyValue = currentDataValue.split(" = ");
        String expectedField = keyValue[0];
        String expectedValue = keyValue[1];
        expectedFieldValueMap.put(expectedField, expectedValue);
    }

Затем выполните итерацию по списку входных объектов (использовали класс Employee с полями id и name и подготовили список тестовых данных с несколькими объектами Employee, называемыми inputEmployeeList, которые итерируются) и посмотрите, проходят ли все фильтры, используя отражение, хотя и медленное, это один из способов:

for (Employee e : inputEmployeeList) {
            try {
                boolean filterPassed = true;
                for (String expectedField : expectedFieldValueMap.keySet()) {
                    String expectedValue = expectedFieldValueMap.get(expectedField);

                    Field fieldData = e.getClass().getDeclaredField(expectedField);
                    fieldData.setAccessible(true);
                    if (!expectedValue.equals(fieldData.get(e))) {
                        filterPassed = false;
                        break;
                    }
                }

                if (filterPassed) {
                    System.out.println(e + " object passed the filter");
                }

            } catch (Exception any) {
                any.printStackTrace();
                // handle
            }
        }

Вам не хватает третьей строки примера: Как получить доступ к члену объекта по имени (и отфильтровать массив по его значению)?

Izruo 07.06.2019 19:33

Вопрос ОП в том, если я правильно понял, что должно заменить вашу строку sysout.

sp00m 07.06.2019 19:41
Ответ принят как подходящий

Вы можете использовать отражения для получения полей класса по динамическому имени.

@Test
void test() throws NoSuchFieldException, IllegalAccessException {
    String[] filters = {"id=123", "name=foo"};

    List<Item> list = newArrayList(new Item(123, "abc"), new Item(2, "foo"), new Item(123, "foo"));

    Class<Item> itemClass = Item.class;

    for (String filter : filters) {
        String key = StringUtils.substringBefore(filter, " = ");
        String value = StringUtils.substringAfter(filter, " = ");

        Iterator<Item> iterator = list.iterator();
        while (iterator.hasNext()) {
            Item item = iterator.next();

            Field field = itemClass.getDeclaredField(key);
            field.setAccessible(true);
            Object itemValue = field.get(item);

            if (!value.equals(String.valueOf(itemValue))) {
                iterator.remove();
            }
        }
    }

    assertEquals(1, list.size());
}

Но я согласен с комментарием от sp00m - это медленно и потенциально опасно.

Другие вопросы по теме