Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
25.08.2014, 18:50     Сделать копию static объекта #1
Здравствуйте. Есть static класс Utils - работает с ArrayList(добавляет элементы, удаляет, выдает нужный по определенным критериям). Есть AsynkTask, который скачивает с сервера файл, который, в свою очередь, парсится в этот ArrayList(1 файл - 1 элемент ArrayList'a). Проблема в том что этот ArrayList статичный, и при обновлении данных все чему было присвоено его значение - тоже обновляется. А мне нужно чтобы обновлялся только он сам, а все остальное осталось старым. Как это можно реализовать оставив класс и ArrayList статичным? Можно ли вообще?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
25.08.2014, 19:13     Сделать копию static объекта #2
можно.
в месте где используется статичный список создать новый.
static ArrayList static = ...;
ArrayList nonstatic = new ArrayList(static);
// дальше юзать nonstatic
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 10:48  [ТС]     Сделать копию static объекта #3
Что то не вышло, сравниваю ArrayList который был создан до обновления с ArrayList'ом после обновления. Они идентичны, даже не идентичны, а это один и тот же лист. Как такое возможно? Смотрел в отладчике. Писал логи при создании старого листа - лог выводится один раз, т.е. присваивание не повторяется после обновления. Но лист уже новый. Что можно еще попробовать?

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

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

Добавлено через 4 минуты
Ид листов разный, а вот ид элементов в них одинаковый. Похоже последнее подозрение верно.
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 11:05     Сделать копию static объекта #4
хоть бы код посмотреть
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 11:13  [ТС]     Сделать копию static объекта #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'ов разные ид. 
        
    }
 
 
}
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 11:28     Сделать копию static объекта #6
а где в коде реализован совет, который выше дал Netscape ?
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 11:33  [ТС]     Сделать копию static объекта #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);
        
    }
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 11:55     Сделать копию static объекта #8
мне трудно вникнуть в твой код, я в процессе изучения языка
по идее new ArrayList<>(staticList); делает не глубокую копию обхекта, то есть так не катит

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

Самое интересно, что statList.equals(list) говорит true, но это все же разные объекты.
Хотя там можно и просто написать list.addAll(staticList); вместо Collections бла бла.
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 12:10     Сделать копию static объекта #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.
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 12:16     Сделать копию static объекта #10
Netscape, нет, не shallow
это просто метод копирования всех элементов из одного листа в другой, а сам объект создается строкой выше
и цикл там вообще ни к чему, либо через Collections.copy либо list.addAll
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 12:18  [ТС]     Сделать копию static объекта #11
Но при изменении исходного элемента, скопированный тоже изменится. Или нет?
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 12:19     Сделать копию static объекта #12
в моем варианте нет, я до того как написать - проверяю
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 12:33     Сделать копию static объекта #13
Цитата Сообщение от Паблито Посмотреть сообщение
это просто метод копирования всех элементов из одного листа в другой, а сам объект создается строкой выше
это и есть shallow copy.
списки будут разные, но ссылки в них будут указывать на одни и те же объекты.
Паблито
не спать!
1882 / 1616 / 500
Регистрация: 12.05.2014
Сообщений: 5,836
Завершенные тесты: 1
26.08.2014, 12:43     Сделать копию static объекта #14
логично значит я не вник в задачу
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 13:23  [ТС]     Сделать копию static объекта #15
Что то я вообще не понимаю. Считал вообще этот latesOrg из старого файла, потом currentOrg из нового, но они все равно имеют один ид. Как так?
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 14:20     Сделать копию static объекта #16
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ладно. Я не поленился и написал пример:
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] - исходный объект остался таким же
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 14:24  [ТС]     Сделать копию static объекта #17
Цитата Сообщение от Netscape Посмотреть сообщение
после изменение полей клона .... исходный объект остался таким же
А мне то нужно чтобы после изменения полей исходного объекта, клон остался прежним)
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 14:29     Сделать копию static объекта #18
Цитата Сообщение от Spelcrawler Посмотреть сообщение
А мне то нужно чтобы после изменения полей исходного объекта, клон остался прежним)
Для моего кода справедливо и это.
Потому что, исходный объект после клонирования не связан с клоном.
Любое изменение любого из этих объектов не повлияет на другой.
Spelcrawler
521 / 491 / 110
Регистрация: 12.03.2014
Сообщений: 1,641
Завершенные тесты: 1
26.08.2014, 17:23  [ТС]     Сделать копию static объекта #19
А как же это объяснить?
Цитата Сообщение от Spelcrawler Посмотреть сообщение
Считал вообще этот latesOrg из старого файла, потом currentOrg из нового, но они все равно имеют один ид. Как так?
Под ид я имею ввиду ссылку на объект, которую видно в отладчике после @

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

Добавлено через 2 часа 50 минут
И еще такой вопрос: если сделать таким методом, а клонируемый класс содержит не только примитивы - не примитивы опять таки будут меняться в копии при изменении их в оригинале?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2014, 17:30     Сделать копию static объекта
Еще ссылки по теме:

Android Static MediaPlayer
BroadcastReceiver + static переменная Android
Android Singleton или класс с полями static?
Парсинг JSON объекта Android
Android Как вызвать postInvalidate() из static метода?

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

Или воспользуйтесь поиском по форуму:
Netscape
 Аватар для Netscape
371 / 358 / 48
Регистрация: 02.10.2009
Сообщений: 712
Записей в блоге: 4
26.08.2014, 17:30     Сделать копию static объекта #20
Цитата Сообщение от Spelcrawler Посмотреть сообщение
А как же это объяснить?
Не знаю. Честно говоря, мне лень разбираться в вашем коде.
Лучше его просто выкинуть и написать все заново.
Цитата Сообщение от Spelcrawler Посмотреть сообщение
И еще такой вопрос: если сделать таким методом, а клонируемый класс содержит не только примитивы - не примитивы опять таки будут меняться в копии при изменении их в оригинале?
String не примитив, и он не меняется.
Yandex
Объявления
26.08.2014, 17:30     Сделать копию static объекта
Ответ Создать тему
Опции темы

Текущее время: 05:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru