1

I am working on an assignment in Java and having a 2D array. I have created multiple classes and at the moment I am creating the array in each and every class and was wondering if there is an easy way to create the array only once in the whole program and call it in different classes. I have created a 2D array and I don't want to use ARRAYLIST (as per my knowledge ARRAYLIST is used when there is no fixed size of array but in my case I know my ARRAY is 5x5).

Here is a basic example of my code:

public class accounts{
        static int option=0;
        static String[][] resultCard =  new String[][]{ 
            { "", "A", "B", "C", "D", "E"},
            { "Account1", "1", "2","3","4","5" }, 
            { "Account2", "6", "7", "8", "9", "10"}, 
            { "Account3", "11", "12", "13", "14", "15"},
            { "Account4", "16", "17", "18", "19", "20"},
            { "Account5", "21", "22", "23", "24", "25"}
        };

public static void method1() {
//I have entered some code here

}

Then I have created another class as follows:

 public class customers{
            static int option=0;
            static String[][] resultCard =  new String[][]{ 
                { "", "A", "B", "C", "D", "E"},
                { "Account1", "1", "2","3","4","5" }, 
                { "Account2", "6", "7", "8", "9", "10"}, 
                { "Account3", "11", "12", "13", "14", "15"},
                { "Account4", "16", "17", "18", "19", "20"},
                { "Account5", "21", "22", "23", "24", "25"}
            };

    public static void method2() {
    //I have entered some code here
}

I have another class as follows:

public class staff{
            static int option=0;
            static String[][] resultCard =  new String[][]{ 
                { "", "A", "B", "C", "D", "E"},
                { "Account1", "1", "2","3","4","5" }, 
                { "Account2", "6", "7", "8", "9", "10"}, 
                { "Account3", "11", "12", "13", "14", "15"},
                { "Account4", "16", "17", "18", "19", "20"},
                { "Account5", "21", "22", "23", "24", "25"}
            };

    public static void method1() {
    //I have entered some code here
}

public static void method1() {
    //I have entered some code here
}

I want to know that instead of creating the array in each class, is it possible that I create one global array in only 01 class and call the array in different classes.

3
  • Yes, just change the visibility of the array, and call MyClass.resultCard. Commented Sep 5, 2014 at 14:11
  • 1
    Apart from that, please follow Java guidelines for naming classes (first letter capitalized; v.g. public class Staff) Commented Sep 5, 2014 at 14:12
  • 3
    Direct sharing of arrays is a no-no in production code though. They are inherently mutable and would introduce state shared between components. Commented Sep 5, 2014 at 14:14

3 Answers 3

5

Whilst the other answers will work fine for your needs, you should never use public static on a mutable (changeable) field - this means that anyone can change the field anywhere in your application and cause unknown behaviour. Primitives (int double float) won't change if you add final modifier, but an Object like an array can have it's contents modified - only the object reference itself will be constant. As a result - the array is mutable, so you shouldn't use public static on it.

It appears that your String[][] is almost meant to represent a table, with the first element in the String[][] being a header, and each other row being a new row in this table. As a result of this, we can turn your String[][] into something more idiomatic.

We can make each row of your String[][] be represented by an instance of a class. There are a few benefits of this, but namely it means that you can look at it and say "this is X", rather than "this is an array of strings".

public class Account {
    private final String name;
    private final String a, b, c, d, e;

    public Account(String name, String a, String b, String c, String d, String e) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.e = e;
        this.name = name;
    }

    public string getName() { return this.name; }
    public string getA() { return this.a; }
    public string getB() { return this.b; }
    public string getC() { return this.c; }
    public string getD() { return this.d; }
    public string getE() { return this.e; }
}

This encapsulates those fields inside of an object. This is great because it means that first of all, you have control over where your fields are assigned and where they can be changed as well.

Now, we can turn your String[][] into an Account[]. As mentioned above, sharing an array directly is bad practise. How do we get around this? Well, we can create another class that controls the lifetime of these accounts. Since it is a data store, let's call it a repository (NB: This is known as the repository pattern).

public class AccountRepository {
    private final Collection<Account> accounts;
    public AccountRepository(Collection<Account> accounts) {
        this.accounts = accounts;
    }

    public Account getByName(String accountName) {
        // Note that this is very inefficient, and I would not recommend using it in real code
        for(Account account : this.accounts) {
            if(account.getName().equalsIgnoreCase(accountName)) {
                return account;
            }
        }
        // Note: Returning null vs throwing exception is out of scope of this example.
        return null;
    }

    public Iterator<Account> getAccounts() {
        return this.accounts.getIterator();
    }
}

Now this gives us a data store that could potentially be used to store any number of Accounts and from, potentially, any source - we don't need to worry about passing around arrays because we can pass an instance of this around, and the best bit is that we give interested parties an Iterator<Account> and not an Account[]. The reason this is great is because Iterators are immutable - you cannot change them. Seeing this, now, we can create your other two classes (Staff, and Customers - whose names and purposes are another subject for debate outside of this question) and tell them that they don't need to worry about an String[][] - they can just take an instance of AccountRepository in their constructor.

public class Customers {
    private final AccountRepository accountRepository;
    public Customers(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    public void method1() {
        // do something
    }
}

public class Staff {
    private final AccountRepository accountRepository;
    public Staff(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    public void method1() {
        // do something
    }
}

This makes your code a lot more flexible and maintainable and easy to follow. Your Staff and Customers instances would require an AccountRepository to be created, which could be the same one, and those classes would call the methods on the AccountRepository to access the data safely without opportunity for it being changed.

Account[] accounts = new Account[] {
    new Account("Account1", "1", "2", "3", "4", "5"),
    // the rest of the accounts
};

AccountRepository repository = new AccountRepository(Arrays.asList(accounts));
Customers customers = new Customers(repository);
Staff staff = new Staff(repository);

In my opinion you should always try to avoid "static" properties or fields - the usage of which indicates a code smell the majority of the time.

Hope this helps and doesn't confuse you.

Sign up to request clarification or add additional context in comments.

Comments

1

You can have a public class that defines the static variable as public. Then in other classes you can access it with className.variableName or use static import

public class GlobalVariables {
   public static final String[][] resultCard =  new String[][]{ 
                { "", "A", "B", "C", "D", "E"},
                { "Account1", "1", "2","3","4","5" }, 
                { "Account2", "6", "7", "8", "9", "10"}, 
                { "Account3", "11", "12", "13", "14", "15"},
                { "Account4", "16", "17", "18", "19", "20"},
                { "Account5", "21", "22", "23", "24", "25"}
            };
}

And the acccounts.java would look like this

import static GlobalVariables.*;

public class accounts{

   public void someMethod(){
     resultCard[0]. ....
   }
}

In case the variable is constant, you can mark it final.

2 Comments

remember, anyone can change this, these are not threadsafe too
Yep, agree. Won't write such code in production. But looking at the question, the user seems to be novice. So current answer suffice his specific needs.
0

It looks like your array is constant and won't change. When I have constants like this that I use in multiple classes I create a Defaults.java file. In this Defaults-file I can add, pretty obvious, the defaults of the app. In your case it would be something like this:

public class Defaults
{
    public static final String[][] resultCard =  new String[][]{ 
            { "", "A", "B", "C", "D", "E"},
            { "Account1", "1", "2","3","4","5" }, 
            { "Account2", "6", "7", "8", "9", "10"}, 
            { "Account3", "11", "12", "13", "14", "15"},
            { "Account4", "16", "17", "18", "19", "20"},
            { "Account5", "21", "22", "23", "24", "25"}
        };
}

You can then use this array in your other classes like so:

public class customers
{
    private static int option = 0;

    public static void method2() {
        // I have entered some code here

        // You can use the resultCard like so:
        // Defaults.resultCard
        // As an example: Get the "B" in the array:
        String result = Defaults.resultCard[0][2];
    }
}

If you don't want to have a final array, since you want to add, edit or delete from the array I would suggest creating a seperated Model-class for this array, with a Getter and Setter (and perhaps an Add-, Edit- and/or Remove-method).

Fields that are used in this Defaults-file shouldn't be changed and should be public static final.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.