Объект является нулевым, так как второй вызов метода

1

С помощью следующего кода скрипт входит в блок if (mySet! = null) только при первом вызове метода.

Почему со второго вызова mySet результаты mySet null?

Map<Integer, Set<String, String>> mMap;

// ... code to populate the map with correct elements

public String myMethod(int idName)
{
    String html = "";

    Set<String> mySet = mMap.get(idName);
    // Set<String> mySet = new HashSet<>(mMap.get(idName));
    if(mySet != null)
    {
        // the script enters here only at first call?!?!?

        for(String name : mySet)
        {
            html += ", " + name;
        }
        mySet.clear();
    }

    return html;
}

myMethod(1); // return some html
myMethod(1); // return empty html...

Если я заменю эту строку:

Set<String> mySet = mMap.get(idName);

с этой строкой:

Set<String> mySet = new HashSet<>(mMap.get(idName));

это работает при каждом вызове.

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

Теги:
android-studio
reference
variable-assignment

3 ответа

1
Лучший ответ

Это здесь:

Set<String> mySet = new HashSet<>(mMap.get(idName));

создает новый набор, который является копией содержимого, имеющегося у вас на карте. Если вместо этого вы непосредственно работаете с заданным объектом, хранящимся на карте, вы также обновите содержимое "карты".

Вот и все, что нужно сделать: разница между изменением вашей "корневой" карты данных и обновлением копии этих данных.

1

Поскольку Set является объектом типа Reference, то впервые, когда он соответствует условию, а затем очищает набор, теперь набор становится пустым, и поэтому значение, соответствующее 1 становится [] пустым набором. Предположим, что myMap имеет значение: 1, ["1", "2", "3"]

Теперь, когда вы выполняете myMethod(1) в первый раз, он очищает набор, соответствующий значению 1

Теперь значение карты становится: 1, []

Таким образом, он снова удовлетворяет вашему условию if(mySet != null) но ничего не добавляет в переменную html поскольку набор mySet пуст. Итак, он возвращает пустую переменную html.

  • 0
    Начиная со второго вызова, оно не оценивает как true выражение if(mySet != null) .
  • 0
    Во втором вызове ваш набор пуст [], но не null ([]! = Null дает true), поэтому он входит в условие if, но в вашем цикле for вы обращаетесь к (String name: mySet) как mySet пустой, он ничего не добавляет к переменной html и возвращает пустую переменную html
Показать ещё 3 комментария
0

Я думаю, что вы можете исправить это с помощью клона mymap.get(idName) в myset

    public String myMethod(int idName)
{
    String html = "";

    Set<String> mySet = (Set<String>) ((HashSet<String>) mymap(idName)).clone();

    if(mySet != null)
    {
        // the script enters here only at first call?!?!?

        for(String name : mySet)
        {
            html += ", " + name;
        }
        mySet.clear();
    }

    return html;
}
  • 0
    change mySet variable as HashSet Я думаю, что это бесполезно; вместо этого это сделает код менее понятным, так как поддерживая его как Set, я могу изменить класс реализации при необходимости, без изменения типа переменной.
  • 0
    Спасибо! Я изменил код
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню