С помощью следующего кода скрипт входит в блок 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
установлены правильно, каждый вызов выполняется без изменения активности, без вращения устройства и других действий.
Это здесь:
Set<String> mySet = new HashSet<>(mMap.get(idName));
создает новый набор, который является копией содержимого, имеющегося у вас на карте. Если вместо этого вы непосредственно работаете с заданным объектом, хранящимся на карте, вы также обновите содержимое "карты".
Вот и все, что нужно сделать: разница между изменением вашей "корневой" карты данных и обновлением копии этих данных.
Поскольку Set является объектом типа Reference, то впервые, когда он соответствует условию, а затем очищает набор, теперь набор становится пустым, и поэтому значение, соответствующее 1
становится []
пустым набором. Предположим, что myMap имеет значение: 1, ["1", "2", "3"]
Теперь, когда вы выполняете myMethod(1)
в первый раз, он очищает набор, соответствующий значению 1
Теперь значение карты становится: 1, []
Таким образом, он снова удовлетворяет вашему условию if(mySet != null)
но ничего не добавляет в переменную html
поскольку набор mySet
пуст. Итак, он возвращает пустую переменную html.
Я думаю, что вы можете исправить это с помощью клона 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;
}
change mySet variable as HashSet
Я думаю, что это бесполезно; вместо этого это сделает код менее понятным, так как поддерживая его как Set, я могу изменить класс реализации при необходимости, без изменения типа переменной.
true
выражениеif(mySet != null)
.