Как заполнить двухмерный ArrayList в Java целыми числами? - PullRequest
5 голосов
/ 17 февраля 2011

Я должен создать 2d массив с неизвестным размером. Поэтому я решил использовать 2d ArrayList, проблема в том, что я не уверен, как инициализировать такой массив или хранить информацию.

Скажите, у меня есть следующие данные

   0 connects 1
   2 connects 3 
   4 connects 5

.... и т. Д. До огромного количества случайных соединений

и я хочу вставить

true(1) into [0][1], 
true(1) into [2][3], 
true(1) into [4][5]. 

Может ли массив автоматически обновлять столбец / строки для меня

Любая помощь приветствуется, спасибо

Ответы [ 7 ]

18 голосов
/ 17 февраля 2011

Я не уверен, как инициализировать такой массив или хранить информацию.

Например, например:

List<List<Integer>> twoDim = new ArrayList<List<Integer>>();

twoDim.add(Arrays.asList(0, 1, 0, 1, 0));
twoDim.add(Arrays.asList(0, 1, 1, 0, 1));
twoDim.add(Arrays.asList(0, 0, 0, 1, 0));

или как это, если вы предпочитаете:

List<List<Integer>> twoDim = new ArrayList<List<Integer>>() {{
    add(Arrays.asList(0, 1, 0, 1, 0));
    add(Arrays.asList(0, 1, 1, 0, 1));
    add(Arrays.asList(0, 0, 0, 1, 0));
}};

Чтобы вставить новую строку, вы должны сделать

twoDim.add(new ArrayList<Integer>());

и добавить другой элемент в конкретный row, который вы делаете

twoDim.get(row).add(someValue);

Вот более полный пример:

import java.util.*;

public class Test {

    public static void main(String[] args) {

        List<List<Integer>> twoDim = new ArrayList<List<Integer>>();

        String[] inputLines = { "0 1 0 1 0", "0 1 1 0 1", "0 0 0 1 0" };

        for (String line : inputLines) {
            List<Integer> row = new ArrayList<Integer>();

            Scanner s = new Scanner(line);
            while (s.hasNextInt())
                row.add(s.nextInt());

            twoDim.add(row);
        }
    }
}
15 голосов
/ 17 февраля 2011
List<List<Integer>> array = new ArrayList<List<Integer>>();
// add row:
array.add( new ArrayList<Integer>() );
// add a column:
array.get( array.size() -1 ).add( 1 );

Рабочая демоверсия:

import java.util.*;
import static java.lang.System.out;
class Load { 
    public static void main( String ... args ) { 

        List<List<Integer>> array = new ArrayList<List<Integer>>();

        Scanner input = new Scanner(System.in);
        out.println("Enter n:");
        int n = input.nextInt();

        out.println("Enter m:");
        int m = input.nextInt();

        out.println("Enter the values:");

        for( int i = 0 ; i < n ; i++ ) { 
            // add row:
            List<Integer> list = new ArrayList<Integer>();
            array.add( list );
            for( int j = 0 ; j < m ; j++ ) { 
                // add a column:
                // array.get( array.size() -1 ).add( 1 ); or
                list.add( input.nextInt() );
            }
        }
        out.println("Result:");
        out.println( array );

    }
}

Выход:

C:\>java Load
Enter n:
3
Enter m:
6
Enter the values
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Result:
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17]]
0 голосов
/ 17 февраля 2011

Поскольку вам нужно хранить только логические значения в этом двумерном массиве, я бы сказал, что наиболее подходящей структурой данных (как по потреблению памяти, так и по полезному интерфейсу) будет java.util.BitSet, который в основном представляет собой класс, моделирующий битовый массив:

Поскольку это двумерный массив, я думаю, что путь будет следующим:

List<BitSet> bitArrays = new ArrayList<BitSet>();

В списке нельзя просто сказать: «вот 5-й элемент», не вставив первый4 элемента.Но в BitSet вы можете просто set() любой необходимый бит, и он автоматически расширится до требуемого размера.

0 голосов
/ 17 февраля 2011

Ваш пример выглядит так, как будто вы хотите получить карту от пар целых чисел до логических значений (значение по умолчанию равно false). Если это разреженная карта (т. Е. На самом деле большинство позиций ложные), вам может быть лучше с чем-то вроде HashSet или аналогичным (с классом, инкапсулирующим два целых с подходящей реализацией hashCode и equals).

class IntPair {
   int first;
   int second;
   public boolean equals(Object o) {
      return o instanceof IntPair &&
         ((IntPair)o).first == first &&
         ((IntPair)o).second == second;
   }
   /** optimized for small numbers */
   public int hashCode() {
       return first + second * 44729;
   }
   public String toString() {
     return "(" + first + ", " + second + ")";
   }
}

Затем, чтобы сказать "0 подключает 1", вы должны написать

set.add(new IntPair(0,1));

Это действительно зависит от того, какие операции вы хотите использовать впоследствии - такой HashSet имеет быстрый поиск и изменение и использует не слишком много места, но вы не можете быстро получить «всех соседей узла 1». Если вам нужен такой доступ, вы можете просто захотеть класс типа

class Node {
   int id;
   Set<Node> neighbours;
}

и дополнительно список / массив / набор таких узлов.

Вопрос «массив неизвестного размера» не достаточно конкретен, чтобы действительно ответить компетентно.

0 голосов
/ 17 февраля 2011

Что ж, если вы знаете, что у вас есть 3 строки и 5 столбцов (как показано в примере с вашими данными), вы можете инициализировать его следующим образом:

int[][] a = new int[3][5]; 

Однако, если количество строк изменяется, вы можете сделать что-то вроде этого:

String dataStr = "0,1,0,1,0:0,1,1,0,1:0,0,0,1,0";

String[] rows = dataStr.split(":");

String[] cols = rows[0].split(",");

Теперь вы можете инициализировать:

int[][] a = new int[rows.length][cols.length];

Это позволит изменить размер строки и столбца. Возможно, это не самый элегантный подход, но он должен работать.

0 голосов
/ 17 февраля 2011

Если у вас нет всех данных заранее, чтобы иметь возможность использовать решение aioobe, вы можете использовать таблицу из библиотеки Google в Google.Невероятно быстрый и неэффективно использующий память, если вы работаете с большим количеством данных, поскольку все это поиск по хешу, а примитивы упакованы в Integer.

0 голосов
/ 17 февраля 2011

Короткий ответ на следующий вопрос:

array.get(i1).put(i2, value);

, но и get, и put могут потерпеть неудачу, если размер ArrayList равен <= index.Поэтому, если вы хотите иметь возможность заполнять произвольные значения, вам нужно написать методы для расширения по мере необходимости.Тогда вызов будет выглядеть примерно так: </p>

putCell(getRow(array, i1), i2, value)

, где getRow () знает, как вырастить ArrayList ArrayList, а putCell () знает, как вырастить ArrayList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...