Что самое легкое альтернативно к универсальному массиву в Java?

В tools_android имеется текущее решение для интеграции Crashlytics в Bazel, названное crashlytics_android_library. Это выглядит так:

GOOGLE_SERVICES_RESOURCES = google_services_xml(
    package_name = "com.example.package",
    google_services_json = "google-services.json",
)

crashlytics_android_library(
    name = "crashlytics_lib",
    package_name = "com.example.package",
    build_id = "9dfea8fe-4d75-48a7-ba28-4ddb7fe74780",
    resource_files = GOOGLE_SERVICES_RESOURCES,
)

Для получения дополнительной информации см. README в bazelbuild/tools_android .

9
задан 20 December 2008 в 23:45
поделиться

6 ответов

Самая легкая альтернатива универсальному массиву должна использовать список.

8
ответ дан 4 December 2019 в 08:17
поделиться

Я могу быть неправым, но Ваше объявление кажется странным, не были должны Вы иметь:

private T[] elements;
0
ответ дан 4 December 2019 в 08:17
поделиться

Проблема состоит в том что начиная с универсального параметра типа T преобразовывается в Object компилятором (это назвало стирание типа), Вы на самом деле создаете массив Object. То, что можно сделать, обеспечивают a Class<T> к функции:

class test<T>
{
    private T[] elements;
    private int size;
    public test(Class<T> type, int size)
    {
        this.size = size;
        elements = (T[]) Array. newInstance(type, size);
    }
}

Вы найдете лучший exlanation его здесь: Angelika Langer - я могу создать массив, чей тип компонента является параметром типа?

13
ответ дан 4 December 2019 в 08:17
поделиться

Я стараюсь по возможности избегать использования базовых массивов и использовать ArrayLists (или аналогичные списки ) по разным причинам. Два наиболее важных:

  1. Мне не нужна семантика лысого массива. Ничто в скобочной нотации (т. Е. Сокращение для арифметики указателей) не делает мою жизнь проще.

  2. Если я использую списки, я настраиваю себя на использование более сложных структур с поддержкой параллелизма в будущем, по мере необходимости. Например, очень просто заменить ArrayList на CopyOnWriteArrayList .

Итак, написание вашего примера с использованием универсального ArrayList будет выглядеть примерно так:

class test<T> {
    /** It's not strictly necessary to make this a List vs. an ArrayList
        You decide what interface you really need to expose internally. */
    private List<T> elements;
    /** This parameter isn't necessary with a List.  You can always call the
        size() method instead. */
    private int size;
    public test(int size) {
        this.size = size;
        elements = new ArrayList<T>();
        // Note that the next line isn't strictly necessary.
        // An ArrayList can be dynamically resized without any real effort on your part.
        elements.ensureCapacity(size); 
    }
}
3
ответ дан 4 December 2019 в 08:17
поделиться

Есть два решения, которые не требуют передачи в объект класса. В обоих случаях я предполагаю, что, поскольку это частная переменная, вы - единственный человек, который помещает вещи в нее, а внешний мир ее не видит.

Один из них - просто использовать простой массив объектов Object [] . Недостатком является то, что вы потеряете преимущества дженериков и вам придется разыгрывать исходящие из него вещи, что делает код более уродливым. Но так как вы единственный, кто вкладывает в это вещи, то актерский состав всегда должен быть в безопасности. Снаружи не нужно знать, что происходит.

Другие варианты - своего рода взлом. Вы создаете Object [] , а затем «приводите» его к T [] . Технически это незаконно, потому что Object [] и T [] - это разные типы времени выполнения, и первый не может быть приведен ко второму. Но до тех пор, пока вы не передадите массив из класса (например, вернете его или что-то еще), это не вызовет никаких проблем, потому что T [] будет стерто в Object [] в любом случае, и на самом деле не выполняется приведение. Тогда вы можете воспользоваться преимуществами обобщений в своем классе для упрощения кодирования, но вы должны быть предельно осторожны, чтобы не передавать этот массив любому, кто действительно ожидает T [] , потому что это не так.

потому что T [] будет стерто в Object [] в любом случае, и на самом деле не выполняется приведение. Тогда вы можете воспользоваться преимуществами обобщений в своем классе для упрощения кодирования, но вы должны быть предельно осторожны, чтобы не передавать этот массив любому, кто действительно ожидает T [] , потому что это не так.

потому что T [] будет стерто в Object [] в любом случае, и на самом деле не выполняется приведение. Тогда вы можете воспользоваться преимуществами обобщений в своем классе для упрощения кодирования, но вы должны быть предельно осторожны, чтобы не передавать этот массив любому, кто действительно ожидает T [] , потому что это не так.

2
ответ дан 4 December 2019 в 08:17
поделиться

Поле размера выглядит избыточным. Вы можете просто использовать elements.length вместо size.

class Test<T> {
    private final T[] elements;
    public test(int size) {
        elements = (T[]) new Object[size];
    }
}

Или вы можете заменить класс Test на ArrayList. то есть бросить класс вообще.

0
ответ дан 4 December 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: