Упростить код создания массивов

177
03 ноября 2019, 14:40

Поскажите пожалуйста, можно ли упростить такой код? Или так и писать на 20 Case?

ArrayList<String[]> gallery_arr_0 = new ArrayList();
    ArrayList<String[]> gallery_arr_1 = new ArrayList();
    ArrayList<String[]> gallery_arr_2 = new ArrayList();
    ArrayList<String[]> gallery_arr_3 = new ArrayList();
    ArrayList<String[]> gallery_arr_4 = new ArrayList();
    ArrayList<String[]> gallery_arr_5 = new ArrayList();
    ArrayList<String[]> gallery_arr_6 = new ArrayList();
    ArrayList<String[]> gallery_arr_7 = new ArrayList();
    ArrayList<String[]> gallery_arr_8 = new ArrayList();
    ArrayList<String[]> gallery_arr_9 = new ArrayList();
    ArrayList<String[]> gallery_arr_10 = new ArrayList();
    ArrayList<String[]> gallery_arr_11 = new ArrayList();
    ArrayList<String[]> gallery_arr_12 = new ArrayList();
    ArrayList<String[]> gallery_arr_13 = new ArrayList();
    ArrayList<String[]> gallery_arr_14 = new ArrayList();
    ArrayList<String[]> gallery_arr_15 = new ArrayList();
    ArrayList<String[]> gallery_arr_16 = new ArrayList();
    ArrayList<String[]> gallery_arr_17 = new ArrayList();
    ArrayList<String[]> gallery_arr_18 = new ArrayList();
    ArrayList<String[]> gallery_arr_19 = new ArrayList();
    //цикл на 20 карт
    for(int i = 0; i < 20; i++) {
        String FileName = mapsActivity.myFolder_Points + "/" + mapsActivity.arr_namePointsTxtFile[i];
        try {
            Scanner Scnr = new Scanner(new File(mapsActivity.Directory_Catalog_of_pathFilesTXT_Points_in_Map,
                    FileName)).useDelimiter("\n");
            while (Scnr.hasNext()) {
                String[] Cols = Scnr.next().split("﹀");
                try {
                    switch (i) {
                        case (0):
                            gallery_arr_0.add(new String[2]);
                            ((String[]) gallery_arr_0.get(gallery_arr_0.size() - 1))[0] = Cols[1]; // грузим название маркера
                            ((String[]) gallery_arr_0.get(gallery_arr_0.size() - 1))[1] = Cols[4]; // грузим изображения
                            break;
                        case (1):
                            gallery_arr_1.add(new String[2]);
                            ((String[]) gallery_arr_1.get(gallery_arr_1.size() - 1))[0] = Cols[1]; // грузим название маркера
                            ((String[]) gallery_arr_1.get(gallery_arr_1.size() - 1))[1] = Cols[4]; // грузим изображения
                            break;
                        case (2):
                            gallery_arr_2.add(new String[2]);
                            ((String[]) gallery_arr_2.get(gallery_arr_2.size() - 1))[0] = Cols[1]; // грузим название маркера
                            ((String[]) gallery_arr_2.get(gallery_arr_2.size() - 1))[1] = Cols[4]; // грузим изображения
                            break;
                        case (3):
                            gallery_arr_3.add(new String[2]);
                            ((String[]) gallery_arr_3.get(gallery_arr_3.size() - 1))[0] = Cols[1]; // грузим название маркера
                            ((String[]) gallery_arr_3.get(gallery_arr_3.size() - 1))[1] = Cols[4]; // грузим изображения
                            break;
                    }

                } catch (Exception e) {
                }
            }
        } catch (Exception e1) {
        }
    }

ДЕЛАЮ ТАК:

public class MyObject {
    String name, imgUrl;
    String[] params;
    public MyObject(){
        params = new String[20];
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getImgUrl() {
        return imgUrl;
    }
    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }
}

.........
myObjects = new ArrayList<>();
    //цикл на 20 карт
    for(int i = 0; i < 20; i++) {
        String FileName = mapsActivity.myFolder_Points + "/" + mapsActivity.arr_namePointsTxtFile[i];
        try {
            Scanner Scnr = new Scanner(new File(mapsActivity.Directory_Catalog_of_pathFilesTXT_Points_in_Map,
                    FileName)).useDelimiter("\n");
            while (Scnr.hasNext()) {
                String[] Cols = Scnr.next().split("﹀");
                    MyObject myObject = new MyObject();
                    myObject.setName(Cols[1]);
                    myObject.setImgUrl(Cols[4]);
                    myObjects.add(myObject);
            }
        } catch (Exception e1) {
        }
    }

    mapsActivity.z_Timer.textview_test.setText(myObjects.get(1).getName());

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

Answer 1

Упростить Ваш код можно - обернуть все списки ещё в один список, массив или, как уже советовали, в Map (если нужно и проще обращаться по ключу, а не по индексу).
Пример со списком:

ArrayList<ArrayList<String[]>> galleries = new ArrayList<>();
//цикл на 20 карт
for (int i = 0; i < 20; i++) {
    String FileName = mapsActivity.myFolder_Points + "/" + mapsActivity.arr_namePointsTxtFile[i];
    try {
        Scanner Scnr = new Scanner(new File(mapsActivity.Directory_Catalog_of_pathFilesTXT_Points_in_Map,
                    FileName)).useDelimiter("\n");
        ArrayList<String[]> gallery = new ArrayList<>();
        while (Scnr.hasNext()) {
            try {
                String[] Cols = Scnr.next().split("﹀");
                String[] strings = new String[2];
                strings[0] = Cols[1]; // грузим название маркера
                strings[1] = Cols[4]; // грузим изображения
                gallery.add(strings);
            } catch (Exception e) {
            }
        }
        galleries.add(gallery);
    } catch (Exception e) {
    }
}

В случае с кастомным классом-моделью - заменяем String[] strings на него.

UPDATE: получение значений:

String[] strings = galleries.get(indexOfFile).get(indexOfLine);

Дальше думаю Вы знаете. И не забываем, что индексы считаются с нуля.

Answer 2

Не стоит заводить отдельные переменные для хранения данных из разных файлов, и не стоит использовать case таким образом. Не нужно также описывать мелкую возню с чтением файлов прямо в том коде, который будет пользоваться этими данными -- лучше вынести это в отдельные методы. Иначе код получается громоздким, его трудно понимать и трудно будет изменить в случае изменения требований к программе.

Данные из всех файлов можно хранить в одной структуре, это может быть массив списков, или список списков, или специально созданный класс для хранения (и, может быть, какой-то обработки) ваших данных. Соображения, высказанные Jarvis_J в соседнем ответе, вполне резонны -- структура фалов может измениться, и вам могут понадобиться дополнительные поля -- в этом случае лучше создать специальные классы.

По существу же вопроса -- конкретных вариантов может быть много, выбор наилучшего зависит от конкретной задачи и ваших предпочтений, вот один из возможных:

  // Названия ваших файлов, можно получить список имен файлов  
  // из директории или как-то еще
  String[] fileNames = { 
    "file_01", "file_02", // ... Сколько надо
  };    
  // Вот это будут данные, класс DataCollection описан ниже  
  DataCollection fileData;
  void doTheWork() { // Собственно работа с данными 
    // Загружаем файлы: 
    fileData = new DataCollection(fileNames);
    // Имя маркера и имя изображения из 10-го элемента 5-го файла:
    System.out.println(fileData.getMarkerName(5, 10));
    System.out.println(fileData.getImgName(5, 10));
  }
  // Класс, который хранит данные и делает всю работу с ними
  class DataCollection {
    // Конструктор загружает данные из файлов
    public DataCollection(String[] fileNames) {
      for (String fileName: fileNames)
        fileData.add(loadFile(fileName));
    }

    public String getMarkerName(int fileIdx, int itemIdx) {
      return getItem(fileIdx, itemIdx).getMarkerName();
    }
    public String getImgName(int fileIdx, int itemIdx) {
      return getItem(fileIdx, itemIdx).getImgName();
    }
    // Остальные детали извне не видны 
    // и внешним кодом не используются
    private class DataItem { // Это один элемент данных
      private String markerName, imgName;
      // Конструктор создает объект данных с полученными значениями
      DataItem(String markerName, String imgName) { 
        this.markerName = markerName;
        this.imgName = imgName;
      }
      String getMarkerName() { return markerName; }
      String getImgName() { return imgName; }
    }
    // Собственно коллекция с данными:  
    private ArrayList<ArrayList<DataItem>> fileData = new ArrayList<>(); 

    // Данные читаются из одного файла и возвращаются в виде списка 
    private ArrayList<DataItem> loadFile(String fileName) {
      ArrayList<DataItem> data = new ArrayList<>();
      Scanner scanner = new Scanner(new File(fileName)).useDelimiter("\n");
      while (scanner.hasNext()) {   // Собственно чтение
        String[] Cols = scanner.next().split("﹀");
        data.add(new DataItem(Cols[1], Cols[4])); // Новый элемент данных
      };
      scanner.close();      // Не забывать!
      return data;
    }
    // Получить элемент данных
    private DataItem getItem(int fileIdx, int itemIdx) {
      if (fileIdx < 0 || fileIdx >= fileData.size()) 
        throw new Exception("Нет файла # " + fileIdx);
      if (itemIdx < 0 || itemIdx >= fileData.size()) 
        throw new Exception("В файле # " + fileIdx + " нет элемента # " + itemIdx);
      return fileData.get(fileIdx).get(itemIdx);
    }
  } // static class DataCollection {

Это только скелет, схема, иллюстрирующая подход, сюда еще следует добавить обработку возможных ошибок (нет файла и т. п.)

Answer 3

Создаёте свой кастомный класс, например, MyObject:

public class MyObject {
    private static final String NAME = 0;
    private static final String URL = 1;
    ArrayList<String[]> params;
    public MyObject(){
        params = new String[количество];
    }
    public String getName(int position) {
        return params.get(position)[NAME];
    }
    public void setName(int position, String name) {
        params.get(position)[NAME] = name;
    }
    public String getImgUrl() {
         return params.get(position)[URL];;
    }
    public void setImgUrl(int position, String imgUrl) {
        params.get(position)[URL] = imgUrl;
    }
}

Далее, создаете 1 массив его элементов:

ArrayList<MyObject> myObjects;
...
myObjects = new ArrayList<>();
for (int i = 0; i < NUMBER; i++) {
        MyObject myObject = new MyObject();
        myObject.setName(col[1]);
        myObject.setImgUrl(col[4]);
        myObjects.add(myObject);
}

Далее, работаете с массивом:

myObjects.get(position1).getName(position2);

Если вы хотите получить доступ к массиву из любой точки приложения создаете этот массив в классе синглтон:

public class Single{
ArrayList<MyObject> myObjects;
private static Single sSingle;
public static Single get(Context ctx) {
    if (sSingle== null) sSingle = new Single(ctx);
    return sSingle;
}
private Single(Context ctx) {
    ... создание и заполнение массива
}
}
public ArrayList<MyObject>(){
    return myObjects;
}

Доступ из любой точки по команде Single.get(контекст).getMyObjects()

Понятно, что вы можете наполнить класс MyObject любыми необходимыми данными в любом количестве совершенно не меняя архитектуру кода.

Answer 4

Попробуйте создать
ArrayList< Map < String, Object > > data;

И создав новый объект Map - HashMap, по ключу и значению записать нужные данные, например, через цикл.

Нашел часть кода с использованием этого принципа, но он не совсем по теме

https://startandroid.ru/ru/uroki/vse-uroki-spiskom/110-urok-51-simpleadapter-dobavlenie-i-udalenie-zapisej.html

UPD: Прочитал комменты, ну тк если сделать как выше написано, можно будет и расширять Map, если понадобится добавить больше параметров и в цикле при обходе можно будет сверять количество параметров, удалять по ключу и удалять не нужные параметры. (Прошу сказать если что то не так написал или понял)

READ ALSO
JFrame и JPanel в JAVA. не все отрисовываются

JFrame и JPanel в JAVA. не все отрисовываются

мое задание - написать имитацию тараканьих бегову меня есть такие классы: Game - основной класс, создает JFrame и принимает входной параметр (количество...

170
Не работаєт @NotNull

Не работаєт @NotNull

@NotNull это аннатоция из пакета javaxvalidation

143
Алгоритм генерации уникальных чисел

Алгоритм генерации уникальных чисел

Есть число N, необходимо найти все уникальные числа до 0 до NНапример из чисел 123,132,213,231,312,321 уникальным будет только любое одно, но если N = 321, то скорее...

168
Как обратиться к API VK через node-vk-bot-api

Как обратиться к API VK через node-vk-bot-api

Есть библиотека - node-vk-bot-api Как с помощью нее обратиться например за методом usersget (возвращающее информацию о профиле)

129