Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Как работать с массивами произвольного типа


Автор: yaja 19.3.2006, 23:14
Возникла проблема. Необходимо передавать некоторый массив классу, а класс будет просто обрабатывать его данные. Точнее даже не обрабатывать данные, а преобразовывать их в строки и их просто выводить на экран. Проблема в том, что тип массива должен быть любым, т.е. и int и double и Object (последний не обязателен, но желателен)...
Существует ли какой-то способ одинаково с ними работать??
Преобразовывать данные в строки во внешнем, по отношению к классу, коде не подходит...

Автор: zer 20.3.2006, 10:22
Использовать Object[] у него же есть метод toString()

Автор: LSD 20.3.2006, 10:33
Передавать ссылку как Object (не Object[] а именно Object) а в коде проверять тип массива и обрабатывать его соответсвенно.
Или использовать классы оболочки Integer, Double и т.д.
Добавлено @ 10:37
Цитата(zer @ 20.3.2006, 10:22 Найти цитируемый пост)
Использовать Object[] у него же есть метод toString()

int[] нельзя передать как Object[], и метод toString() вернет что-то вроде [I@a4d5623.

Автор: yaja 21.3.2006, 18:24
LSD, использовать классы оболочки будет слишком накладно...
А передать как Object наверное подойдет. Только как проверять тип передаваемого массива? Делать обычное преобразование типа и проверять вылетает ли исключение? Или есть другой метод?

Автор: powerOn 21.3.2006, 18:39
Есть такая конструкция волшебная instanceof
с её помощью можно выполнить проверку типа

вот примерчик
Код

       Object o = null;
        int i = 1;
        o = i;
        if (o instanceof Integer) {
            System.out.println("Integer!");
        }

Автор: yaja 21.3.2006, 19:43
MoonCat, незнал, что он и с массивами работает smile
Но я все-равно получаю немного не то, что ожидал. Тогда получается некоторый следующий код в классе
Код

class Tmp {
        private int[] intData;
        private double[] doubleData;
        private Object[] objData;
        
        public Tmp(Object o) {
            if (o instanceof int[]) intData = (int[])o;
            else if (o instanceof double[]) doubleData = (double[])o;
            else if (o instanceof Object[]) objData = (Object[])o;
        }
        
        public void paint() {
            if (intData != null) { 
                /* draw int*/ 
            } else if (doubleData != null) {
                /* draw double */
            } else if (objData != null) {
                /* draw Object */
            }
        }
    }


Что безусловно не есть гуд, если вдруг захочется передать массив другого типа... smile
А нельзя ли использовать какой-нибудь стандартный контейнер? Такой, что при изменении самого массива, автоматически обновлялись данные и в контейнере??

Автор: powerOn 21.3.2006, 20:01
Ну тогда, видимо, надо сделать так

Код

class Tmp {

        private Object[] objData =null;
        
        public Tmp(Object [] o) {

        objData = new Object[o.length];
        for(int i = 0; i < o.length; i++) {
            objData[i] = o[i];
        }
            
        }
        
        public void paint() {
            // Здесь добавишь проверку типа 
            if (o instanceof int[]) {}
            else if (o instanceof double[]) {}
            else if (o instanceof Object[]) {}

        }
    }



в зависимоти от решаемой задачи можно доработать метод paint.

smile поправил собственные баги........

Автор: LSD 21.3.2006, 21:18
Проблема в том, что массив примитивного типа приводится только к Object. Соответсвенно даже для того чтобы тебе сделать итерацию по массиву уже надо знать его тип. Поэтому или 10 if-ов или оболочки. Слишком накладными классы оболочки становятся на размерах массива больше 1 000 000.
А в чем проблема с универсальностью? Примитивных типов немного, и они добавляться не будут, а вот все остальный массивы можно передать как Object[].

Конечно есть универсальный вариант с рефлексией. Но он подходит только для Маленького теста, а не практического применения.

Автор: yaja 21.3.2006, 22:16
MoonCat, работать для массивов типа int не будет smile только для объектов.
При использовании оболочек Integer меня смущает то, что будет существовать два никак не связанных объекта, int[] и Integer[] и при изменении первого, второй эти изменения никак не прочуствует smile Сами массивы очень маленькие, порядка 10-20 элементов.

LSD, а как тут рефлексию приплести? Тоесть то, что мне представляется, никак не избавит от большого числа ifов.
Мона считать, что приложение маленькое... smile

Можно же получить два списка, отвечающих одной "области памяти". Например метод subList в java.util.List.. Неужеле нету никаких аналогов для массивов простых типов??

Если честно, не хочется писать 10 if (хотя их там меньше и не особо трудно это сделать) потому, что это как то не по "объектно-ориентированному" smile

Автор: LSD 21.3.2006, 22:31
Цитата(yaja @ 21.3.2006, 22:16 Найти цитируемый пост)
Если честно, не хочется писать 10 if (хотя их там меньше и не особо трудно это сделать) потому, что это как то не по "объектно-ориентированному"

А все из-за того что у нас есть не объекты smile
Так что способ, вполне нормальный.

А про рефлексию, я пожалуй напишу в Маленький тест. Пусть народ развлечется, все равно этот способ нельзя считать практичным smile

Цитата(yaja @ 21.3.2006, 22:16 Найти цитируемый пост)
Можно же получить два списка, отвечающих одной "области памяти". Например метод subList в java.util.List.. Неужеле нету никаких аналогов для массивов простых типов??

Так они разное количество памяти на один элемент занимают, как минимум это мешает.

Автор: powerOn 21.3.2006, 23:11
Цитата

MoonCat, работать для массивов типа int не будет smile только для объектов.


сорри, код "на каленке" писал smile
просто для развития мысли, не больше....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)