1

I want an infinite 2D array in my program. I have the following code for a 2D array:

int a[][]=new int[10][10];

But the problem is that the array is of fixed length, with row and column values.

TZHX
  • 5,291
  • 15
  • 47
  • 56
Dhiraj
  • 870
  • 2
  • 12
  • 25
  • Arrays in Java **are** of fixed size. – Kayaman Sep 09 '15 at 11:45
  • 2
    By "infinite", you mean an array that goes on forever? Have you looked at ArrayLists? (Just so you know, they don't go on forever) – Ḟḹáḿíṅḡ Ⱬỏḿƀíé Sep 09 '15 at 11:46
  • Depending on how sparse your matrix will be, you can consider implementing a structure of arrays, each representing a small portion of an enormous (and mostly empty) whole. – Tony Ennis Sep 09 '15 at 12:17
  • You might get better answers if you explain why it needs to be "infinite". You seem to want to have an int value for certain X,Y coordinates without specifying a maximum X or Y. You can't store infinite data in memory, so clearly you need to think about when a particular X,Y coordinate value (or 2D range of values) needs to be initialized and/or modified and when it needs to be read. You might need "pages" of finite 2D arrays that you load when the info needs to be displayed to the user, or if the data is very sparse, a Map> might be the best solution. – aro_tech Sep 09 '15 at 12:41

4 Answers4

4

As Kayaman commented, arrays in java are fixed size as specified in JLS (§10.3)

An array creation expression specifies the element type, the number of levels of nested arrays, and the length of the array for at least one of the levels of nesting. The array's length is available as a final instance variable length.

You have 3 alternatives, if first is not possible in your case, you should use 2nd one:

  1. use a variable to give array extact size you need:

    int numberOfXElement = // get the elements in dynamic way
    int numberOfYElement = // get the elements in dynamic way
    int a[][]=new int[numberOfXElement][numberOfYElement];
    

BEST OPTION

  1. use ArrayList which has dynamic size and you can add elements without caring the size (but not until infinite, just till Integer.MAX_VALUE).

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

    NOTE: as pointed on comments, take care you are using Integer and not int.


  1. give Integer.MAX_VALUE size to array (but must be careful with empty positions)
    as pointed in comments, syntactically is a correct expression, but you need tones of ram memory to execute it. Instead of this:

    give a big number you will never reach to array when creating, but if you use this option you must be careful with empty positions.

    int a[][]=new int[8043][8043];
    

    Why 8043? I used a quick test to see max heap size in my actual machine, 2gb RAM, does not care which value i starts, always breaks (in my machine, trying to create an int[8044][8044]).

    for (int i = 0; ; i++) {
        int a[][]=new int[i][i];
        System.out.println(i + " " + Arrays.toString(a));
    }
    
Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • 3
    Good luck with the third one. Unless you have a few billion gigs of ram. I think the list approach would be the best. – chasep255 Sep 09 '15 at 12:19
3

Arrays are fixed in size. Once you declare them with some length, you cannot change it later.

You might want to have an ArrayList which increase size dynamically while you keep adding the items.

If you are looking for 2D, ArrayList of ArrayList will be the option.

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

And if you don't exactly know why I wrote List<List<>> instead of ArrayList<ArrayList>> on left side, please refer Type List vs type ArrayList in Java

Community
  • 1
  • 1
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
1

Not sure if it's possible to create a stream of streams, but in Java 8 you can have infinite streams.

https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#generate-java.util.function.IntSupplier-

Viktor Mellgren
  • 4,318
  • 3
  • 42
  • 75
1

Declare yourself a class Point with equals and hashCode - something like this:

    class Point {

        private final int x;
        private final int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 79 * hash + this.x;
            hash = 79 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

    }

Then use a:

Map<Point,Value> twoDArray= new HashMap<>();

Setting a particular location to a value would be as simple as:

twoDArray.put(new Point(x,y), value);

If your array is likely to be sparse then there are meny specialst classes that can help.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • @OldCurmudgeon can you explain me code more briefly – Dhiraj Sep 10 '15 at 09:21
  • @Dhiraj - Instead of declaring an array or list, use a `Map`. You can then set/clear/get values anywhere in your 2D array just by locating the `Point` and looking it up in the `Map`. – OldCurmudgeon Sep 10 '15 at 09:29