Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
#1

Сделать копию static объекта

25.08.2014, 18:50. Просмотров 1194. Ответов 20
Метки нет (Все метки)

Здравствуйте. Есть static класс Utils - работает с ArrayList(добавляет элементы, удаляет, выдает нужный по определенным критериям). Есть AsynkTask, который скачивает с сервера файл, который, в свою очередь, парсится в этот ArrayList(1 файл - 1 элемент ArrayList'a). Проблема в том что этот ArrayList статичный, и при обновлении данных все чему было присвоено его значение - тоже обновляется. А мне нужно чтобы обновлялся только он сам, а все остальное осталось старым. Как это можно реализовать оставив класс и ArrayList статичным? Можно ли вообще?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.08.2014, 18:50
Ответы с готовыми решениями:

Время жизни static объекта
Приветствую, Что то я запутался с проклятым static, помогите. Дано: ...

Static MediaPlayer
Добрый день! Пытался реализовать следующий алгоритм работы своего приложения:...

BroadcastReceiver + static переменная
Работая с бродкаст ресивером задался вопросом, как же он всё-таки работает?)...

Объявление static без имени
Наткнулся на такой код: private static final UriMatcher uriMatcher;...

Static поле у внутреннего класса
Есть класс, скажем Building, в нем есть еще один класс, скажем Floor. И вот...

20
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
25.08.2014, 19:13 #2
можно.
в месте где используется статичный список создать новый.
static ArrayList static = ...;
ArrayList nonstatic = new ArrayList(static);
// дальше юзать nonstatic
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 10:48  [ТС] #3
Что то не вышло, сравниваю ArrayList который был создан до обновления с ArrayList'ом после обновления. Они идентичны, даже не идентичны, а это один и тот же лист. Как такое возможно? Смотрел в отладчике. Писал логи при создании старого листа - лог выводится один раз, т.е. присваивание не повторяется после обновления. Но лист уже новый. Что можно еще попробовать?

Добавлено через 14 минут
Пробовал даже clone() - результат тот же.

Добавлено через 10 минут
Подозреваю, что пока выполняется AsynkTask, старый лист удаляется из памяти GrabageCollector'ом т.к. он считает его не нужным, а потом когда его требует главный поток инициализирует его заново. Возможно ли такое? И если да, как с этим бороться?

Добавлено через 4 минуты
Ид листов разный, а вот ид элементов в них одинаковый. Похоже последнее подозрение верно.
0
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 11:05 #4
хоть бы код посмотреть
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 11:13  [ТС] #5
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Comparator {
 
    private ArrayList<Organisation> latestOrgs;
    private ArrayList<Organisation> currentOrgs;
 
 
    public Comparator(ArrayList<Organisation> latestOrgs){//Создается перед началом обновления
        ArrayList<Organisation> staticList = new ArrayList<Organisation>(latestOrgs);
        this.latestOrgs = new ArrayList<Organisation>();
        for(int i = 0; i < staticList.size(); i++){
            this.latestOrgs.add(staticList.get(i));
        }
    }
    public void setCurrentOrgs(ArrayList<Organisation> currentOrgs){//Вызывается после обновления
        this.currentOrgs = currentOrgs;
    }
    private Organisation getLatestOrg(String id){
        for(int i = 0; i < latestOrgs.size(); i++){
            if(latestOrgs.get(i).getId().equals(id)){
                return latestOrgs.get(i);
            }
        }
        return null;
    }
    private Organisation getCurrentOrg(String id){
        for(int i = 0; i < currentOrgs.size(); i++){
            if(currentOrgs.get(i).getId().equals(id)){
                return currentOrgs.get(i);
            }
        }
        return null;
    }
    public void compareAmounts(Context context, String id){//Вызывается после setCurrentOrgs() 
        Organisation latestOrg = getLatestOrg(id);
        Organisation currentOrg = OrgUtils.getOrganisation(context, id);
       //Вот после этих строк в отладчике  latestOrg и currentOrg имеют один и тот же ид(ссылку или как это правильно называется), а у ArrayList'ов разные ид. 
        
    }
 
 
}
0
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 11:28 #6
а где в коде реализован совет, который выше дал Netscape ?
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 11:33  [ТС] #7
Цитата Сообщение от Паблито Посмотреть сообщение
а где в коде реализован совет, который выше дал Netscape ?
Java
1
2
3
4
5
6
7
public Comparator(ArrayList<Organisation> latestOrgs){
        ArrayList<Organisation> staticList = new ArrayList<Organisation>(latestOrgs);
        this.latestOrgs = new ArrayList<Organisation>();
        for(int i = 0; i < staticList.size(); i++){
            this.latestOrgs.add(staticList.get(i));
        }
    }
Разве это не оно?
Пробовал и так
Java
1
2
3
4
5
 public Comparator(ArrayList<Organisation> latestOrgs){
        ArrayList<Organisation> staticList = latestOrgs;
        this.latestOrgs = new ArrayList<Organisation>(staticList);
        
    }
0
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 11:55 #8
мне трудно вникнуть в твой код, я в процессе изучения языка
по идее new ArrayList<>(staticList); делает не глубокую копию обхекта, то есть так не катит

я бы сделал так
ArrayList<> list = new ArrayList<>();
Collections.copy(statList, list);

Самое интересно, что statList.equals(list) говорит true, но это все же разные объекты.
Хотя там можно и просто написать list.addAll(staticList); вместо Collections бла бла.
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 12:10 #9
Если нужен deep copy, то как-то так:

Java
1
2
3
4
5
public static List<Organisation> cloneList(List<Organisation> list) {
    List<Organisation> clone = new ArrayList<Organisation>(list.size());
    for(Organisation item: list) clone.add(item.clone());
    return clone;
}
Добавлено через 1 минуту
Конечно, класс Organisation должен реализовать интерфейс Cloneable.

Добавлено через 2 минуты
Паблито,
Цитата Сообщение от Паблито Посмотреть сообщение
ArrayList<> list = new ArrayList<>();
Collections.copy(statList, list);
так же делать только shallow copy.
1
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 12:16 #10
Netscape, нет, не shallow
это просто метод копирования всех элементов из одного листа в другой, а сам объект создается строкой выше
и цикл там вообще ни к чему, либо через Collections.copy либо list.addAll
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 12:18  [ТС] #11
Но при изменении исходного элемента, скопированный тоже изменится. Или нет?
0
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 12:19 #12
в моем варианте нет, я до того как написать - проверяю
1
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 12:33 #13
Цитата Сообщение от Паблито Посмотреть сообщение
это просто метод копирования всех элементов из одного листа в другой, а сам объект создается строкой выше
это и есть shallow copy.
списки будут разные, но ссылки в них будут указывать на одни и те же объекты.
2
Pablito
2708 / 2155 / 731
Регистрация: 12.05.2014
Сообщений: 7,521
Завершенные тесты: 1
26.08.2014, 12:43 #14
логично значит я не вник в задачу
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 13:23  [ТС] #15
Что то я вообще не понимаю. Считал вообще этот latesOrg из старого файла, потом currentOrg из нового, но они все равно имеют один ид. Как так?
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 14:20 #16
Лучший ответ Сообщение было отмечено Spelcrawler как решение

Решение

Ладно. Я не поленился и написал пример:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import java.util.ArrayList;
import java.util.List;
 
public class Main {
    
    public static void main(String[] args) {
        Organisation o1 = new Organisation();
        o1.setId(0);
        o1.setName("first");
        List<Organisation> l1 = new ArrayList<>();
        l1.add(o1);
        System.out.println("first: " + l1.get(0).toString());
        List<Organisation> l2 = cloneList(l1);
        System.out.println("second: " + l2.get(0).toString());
        
        l2.get(0).setId(1);
        l2.get(0).setName("second");
        
        System.out.println("first: " + l1.get(0).toString());
        System.out.println("second: " + l2.get(0).toString());
        System.out.println("first: " + l1.get(0).toString());
    }
    
    public static List<Organisation> cloneList(List<Organisation> list) {
        List<Organisation> clone = new ArrayList<Organisation>(list.size());
        for(Organisation item: list)
            try {
                clone.add(item.clone());
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
        return clone;
    }
    
    static class Organisation implements Cloneable {
        
        private String name;
        private int id;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        
        @Override
        protected Organisation clone() throws CloneNotSupportedException {
            Organisation o = (Organisation) super.clone();
            o.name = this.name;
            o.id = this.id;
            return o;
        }
        @Override
        public String toString() {
            return "Organisation [name=" + name + ", id=" + id + "]";
        }
        
    }
 
}
Вывод в консоли:
first: Organisation [name=first, id=0] - первый объект
second: Organisation [name=first, id=0] - его клон

first: Organisation [name=first, id=0]
second: Organisation [name=second, id=1] - после изменение полей клона
first: Organisation [name=first, id=0] - исходный объект остался таким же
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 14:24  [ТС] #17
Цитата Сообщение от Netscape Посмотреть сообщение
после изменение полей клона .... исходный объект остался таким же
А мне то нужно чтобы после изменения полей исходного объекта, клон остался прежним)
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 14:29 #18
Цитата Сообщение от Spelcrawler Посмотреть сообщение
А мне то нужно чтобы после изменения полей исходного объекта, клон остался прежним)
Для моего кода справедливо и это.
Потому что, исходный объект после клонирования не связан с клоном.
Любое изменение любого из этих объектов не повлияет на другой.
1
Spelcrawler
531 / 501 / 113
Регистрация: 12.03.2014
Сообщений: 1,666
Завершенные тесты: 1
26.08.2014, 17:23  [ТС] #19
А как же это объяснить?
Цитата Сообщение от Spelcrawler Посмотреть сообщение
Считал вообще этот latesOrg из старого файла, потом currentOrg из нового, но они все равно имеют один ид. Как так?
Под ид я имею ввиду ссылку на объект, которую видно в отладчике после @

Добавлено через 1 минуту
Считывание - это у меня десериализация из файла, при ней эти "ид" тоже сохраняются?

Добавлено через 2 часа 50 минут
И еще такой вопрос: если сделать таким методом, а клонируемый класс содержит не только примитивы - не примитивы опять таки будут меняться в копии при изменении их в оригинале?
0
Netscape
374 / 361 / 52
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 17:30 #20
Цитата Сообщение от Spelcrawler Посмотреть сообщение
А как же это объяснить?
Не знаю. Честно говоря, мне лень разбираться в вашем коде.
Лучше его просто выкинуть и написать все заново.
Цитата Сообщение от Spelcrawler Посмотреть сообщение
И еще такой вопрос: если сделать таким методом, а клонируемый класс содержит не только примитивы - не примитивы опять таки будут меняться в копии при изменении их в оригинале?
String не примитив, и он не меняется.
2
26.08.2014, 17:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2014, 17:30

Как сделать копию объекта
Всем привет. Как сделать копию объекта так, чтобы копия могла существовать не...

Как сделать копию объекта без какой-либо связи между ними
Есть следующий код: class Class1 { public int Matrix; public int...

Как изменить свойство non-static объекта из static метода
Понимаю, что такое не задумано средствами Net Framework, но у меня из-за этого...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru