Как я могу инициализировать массив, не зная его размера?

У меня есть ситуация, когда я должен применить критерии к входному массиву и вернуть другой массив в качестве вывода, который будет иметь меньший размер на основе критериев фильтрации.

Теперь проблема в том, что я не знаю размер отфильтрованных результатов, поэтому я не могу инициализировать массив определенным значением. И я не хочу, чтобы он был большого размера с нулевыми значениями, потому что я использую array.length; позже.

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


person Space Rocker    schedule 26.12.2010    source источник


Ответы (4)


Вы не можете... размер массива всегда фиксирован в Java. Обычно вместо массива здесь используется реализация List<T> — обычно ArrayList<T>, но существует множество других доступных альтернатив.

Конечно, вы можете создать массив из списка в качестве последнего шага или просто изменить сигнатуру метода, чтобы он возвращал List<T> для начала.

person Jon Skeet    schedule 26.12.2010
comment
почему в этой ситуации вы бы предпочли ArrayList LinkedList? - person Roman; 26.12.2010
comment
@Roman: Я просто обычно использую ArrayList. LinkedList тоже подойдет... он, конечно, дороже с точки зрения памяти, но не требует копирования элементов при расширении. - person Jon Skeet; 26.12.2010
comment
@Roman: См. Когда использовать LinkedList вместо ArrayList для обсуждения. При этом ваша первая склонность должна быть ArrayList. - person Brian; 27.12.2010

Вместо этого используйте LinkedList. Затем вы можете создать массив, если это необходимо.

person Roman    schedule 26.12.2010
comment
ArrayList, вероятно, будет более подходящим - person Noel M; 26.12.2010
comment
@Ноэль М: почему? Я думаю, что нет. Мы не знаем количество элементов. Итак, с LinkedList каждая операция добавления (т.е. addLast) работает в O(1) и выполняет действительно небольшую работу, в то время как ArrayList будет автоматически увеличивать свой размер в несколько раз, и это дорогостоящие операции. - person Roman; 26.12.2010
comment
С другой стороны, в LinkedList вы создаете объект Node для каждого элемента. Вы утверждаете, что расширение является дорогостоящей операцией - это всего лишь вопрос создания нового массива и копирования существующих элементов (что может быть быстрой копией массива). Я не думаю, что просто сказать, что лучше для этой ситуации. - person Jon Skeet; 26.12.2010

Просто верните любой список. ArrayList подойдет, он не статичен.

    ArrayList<yourClass> list = new ArrayList<yourClass>();
for (yourClass item : yourArray) 
{
   list.add(item); 
}
person stbn    schedule 26.12.2010

Вот код вашего класса. но это также содержит много рефакторинга. Пожалуйста, добавьте для каждого, а не для. ваше здоровье :)

 static int isLeft(ArrayList<String> left, ArrayList<String> right)

    {
        int f = 0;
        for (int i = 0; i < left.size(); i++) {
            for (int j = 0; j < right.size(); j++)

            {
                if (left.get(i).charAt(0) == right.get(j).charAt(0)) {
                    System.out.println("Grammar is left recursive");
                    f = 1;
                }

            }
        }
        return f;

    }

    public static void main(String[] args) {
        // TODO code application logic here
        ArrayList<String> left = new ArrayList<String>();
        ArrayList<String> right = new ArrayList<String>();


        Scanner sc = new Scanner(System.in);
        System.out.println("enter no of prod");
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            System.out.println("enter left prod");
            String leftText = sc.next();
            left.add(leftText);
            System.out.println("enter right prod");
            String rightText = sc.next();
            right.add(rightText);
        }

        System.out.println("the productions are");
        for (int i = 0; i < n; i++) {
            System.out.println(left.get(i) + "->" + right.get(i));
        }
        int flag;
        flag = isLeft(left, right);
        if (flag == 1) {
            System.out.println("Removing left recursion");
        } else {
            System.out.println("No left recursion");
        }

    }
person User123456    schedule 17.01.2014