Basic question from somebody coming from structured into object programming... hoping not to be too basic.
I want to have a large array of data that is been shared by different classes inside my application.
What's the best practice to do this?
Is this correct?
public class LargeData {
private static long[] myData;
private static final int MAX = 100000;
public LargeData() {
myData = new long[MAX];
// ... initialize
}
public long getData(int x) {
// ... do whatever and return a long
}
}
And if this is correct, how is the correct way to access this data from any of my classes? Should I make a
LargeData ld = new LargeData();
inside every single class that wants to access to myData?
Thank you and sorry for being too easy... :)
use a Singleton pattern for this.
Everytime you call
LargeData ld = new LargeData();
in your code, you will be effectively calling
myData = new long[MAX];
which is wrong.
What you can do is:
public class LargeData {
private static final int MAX = 100000;
public static long[] myData = new long[MAX];
}
and access it as LargeData.myData from anywhere.
initialize array immediately. with current implementation you won't be able to use static array until create object of LargeData.
Also if class just for holding array prevent its instantiation and extension by making it final and constructor as private.
public final class LargeData {
public static long[] myData = new long[100000];
private LargeData() { }
}
And get access as LargeData.myData
Assigning values to static variables from instance constructors is a bad idea without a null check - if you ever instantiate two objects from this class the second will cause you to lose all data stored in the array (you lose the reference to the old array when the second instantiation overwrites the static reference). With null check it is also a bad idea though, unless you really really really need the data in one instance sort of a "global variable" way. It is best to think of static references as global variables which can be either viewable by all (if they are public) or visible only from the class you define it in (private) or something in between (protected or package protected access). You pretty much want to avoid using them though in almost all cases and use the Singleton pattern instead of static variables inside classes. With the Singleton pattern you use instance variables and non-static getters to get to the data.
However I do not see given the things you wrote why you would need a singleton pattern for this particular problem - you just want to store data in an object and share that object around, right?
You can fix the posted code like this without static keywords and this allows multiple LargeData instances to be alive at once in your application:
public class LargeData {
private long[] myData; // instance variable to store the data
private static final int MAX = 100000; // max length
public LargeData() {
myData = new long[MAX];
}
public long[] getData() {
return myData;
}
}
Then you can use the data as:
LargeData ld = new LargeData();
long[] = ld.getData();
And you can use the reference stored in ld any way you like, you can pass it around your other classes, etc.
A better idea would be to not expose the array, rather create an API through which you use the stored data. For example:
public long getLong(int n) { return myData[n]; }
public void setLong(int n, long value) { myData[n] = value; }
Now if you don't want to pass around the reference to the LargeData instance stored in ld, you can use a static variable in LargeData to store the reference and a static getter which lets you access it from any other java code. If you need multiple LargeData instances to work with you can create a LargeDataRegistry class that encapsulate a Map where you would store each instantiated LargeData instance.
Related
I'm new to coding and I've faced this problem recently: I'm working on a class which has various fields, and I want to insure each instance of the class has a unique value for a certain field using static variables. for example, consider this class:
public class NetworkNode {
private String NodeName;
private int NodeNumber;
private boolean NodeAttraction;
....
}
in the code above, I want to insure each object created from the class NetworkNode to have a unique and different NodeNumber or in other words, no two NetworkNode objects should have the same NodeNumber field.
what are the ways to do this? thanks.
You could automatically assign a different NodeNumber to each instance if you don't care about the actual value as long as it's unique. Using static variables you could create a private static counter nextNodeNumber in your class NetworkNode:
private static int nextNodeNumber = 0;
In your constructor you could then do
public NetworkNode() {
this.NodeNumber = nextNodeNumber;
++nextNodeNumber;
...
}
This way you just have to ensure, that there is no other way to set/change NodeNumber or nextNodeNumber.
If you are using multiple Threads you would have to secure access to nextNodeNumber to prevent asynchronous access.
1 put a
static Set<String> myuniquevalues ... (for example) for each of your fields
2 in your constructor
public NetworkNode (String value1 ...)
{... check if value1 exists in myuniquevalues , and throw exceptions }
3 if your objects are deleted, you must manage it also ...
Alternative: concentrate creation of your objects in a factory, and manage unicity there.
I recommend you to do some reading about variables and what static means. To make it short, a static variable exists only "once" in your program.
For example, if you create a game, you want the variable score to be static since there will only be one instance of this variable.
In order to have each NetworkNode to have a unique and different NodeNumber, you have to construct the object like this:
public NetworkNode(String NodeName, int NodeNumber, boolean NodeAttraction){
this.NodeName = NodeName;
this.NodeNumber = NodeNumber;
this.NodeAttraction = NodeAttraction;
}
See, here, each NetworkNode will have a different value for each of the variables passed as parameters.
You will then just need to create the object in your main function or whatever like this for example:
NetworkNode myNode = new NetworkNode("node1", 0, true);
Hope it helps,
How can I make sure that each instance of a class will have a unique value for a specific parameter?
For example:
public Foo(int value);
value should be different for each instance of Foo. Otherwise, it can throw an exception.
Do you want to assign that value, or do you just want to make sure you have some kind of id?
A minimal solution for an id would be to use a static field as counter:
public class Foo {
private static int counter = 1;
private int id;
public Foo() {
id = counter++;
}
}
To check for assigned values you might want to use some kind of FooFactory:
public class FooFactory {
private static Set<int> ids = new Set<int>();
public static Foo createFoo(int value) {
if (ids.contains(value)) {
throw new FooAlreadyExistsException();
}
ids.add(value);
return new Foo(value);
}
}
Or, as other comments suggest, you could do this in the Foo constructor:
public class Foo {
private static Set<int> ids = new Set<int>();
public Foo(int value) {
if (ids.contains(value)) {
throw new FooAlreadyExistsException();
}
ids.add(value);
}
}
Create a factory:
public Foo createFoo( int value ) {....}
In the factory code, you can maintain a set of "allocated" values. This allows you to optimize the code; for example if the values are consecutive, a BitSet might be better than Set<Integer>. Note that you must "deallocate" your instances of Foo somehow if you want to be able to reuse values.
If you just GC instances of Foo, the value will still be "in use" unless you notify the factory somehow.
Assuming all instances of Foo would be in memory, you can maintain a static Set in the Foo class that would hold the values that were already used. You can check against this Set any time a new instance is created.
Another alternative, assuming there is no functional meaning to this value, is to have some sequence (backed by either a DB or a file) that would increment any time a new instance is created, and the value of each new instance would be the current value of that sequence.
I think your unique value should not be a parameter (which is under control of an arbitrary caller) but a responsibility of Foo.
A simple solution would be to use a static field which is incremented each time an instance is created:
private static int instanceCounter;
// instance initializer
{
instanceCounter++;
}
As others have mentioned this smells of a problem in your design or your understanding of the requirements.
Please share the requirements, your intended design and the code you have created so far.
EDIT: 'Aaron Digulla' has a better suggestion, to create a factory which manages this aspect of the object lifecycle.
I'd propose having a static ArrayList inside of a class, containing a list of your objects. But this is bad design IMHO.
I was wondering what the difference is between
public final type attribute_name;
and
private type attribute_name;
public type getA_name() {
return attribute_name;
}
Basically I want to make an attribute read-only, so it can't change after it has been initialized.
Do I make it public final, or do I make it private, and only make it accesible through a get method (without a set method)?
When it's not final but private, the class itself is able to change the value.
A final field MUST be set before the constructor exits. Once set, the reference cannot be modified (the value cannot be reassigned). Emphasis on the cannot be reassigned. This means that while the reference cannot change, the value itself can change.
This is legal:
final List<Integer> list = new List<Integer>();
list.add(5); // the value of list changes, but the reference doesn't
This is not:
final List<Integer> list = new List<Integer>();
list = new List<Integer>(); // may seem sort of redundant but the compiler won't allow it nonetheless
A private variable with a only getter can be reassigned internally by the class that holds it (but it's not visible externally so it cannot be reassigned outside the class holding it). Also, outside the class the reference is inaccessible so the variable cannot be modified except by the class holding it.
A final variable cannot be reassigned anywhere, but if it's public, another class can still access the reference and change the value of whatever object it points to.
If you don't want the variable to be reassigned after initialization as you described, use both final and private.
Use final for something like this:
public class User {
private final long registrationTimeMillis;
public User(/* various parameters probably would be here */) {
registrationTimeMillis = System.currentTimeMillis();
}
public long getRegistrationTimeMillis() {
return registrationTimeMillis;
}
}
We don't expect that a user's registration time will change, so it makes sense to not allow it to change after construction.
Use private with no setter for something like this:
public class VendingController() {
private int drinksStocked = 0;
private int drinksDispensed = 0;
public void dispenseDrink() {
drinksDispensed++;
}
public void stockDrinks(int numberOfDrinks) {
drinksStocked = getDrinksRemaining() + numberOfDrinks;
drinksDispensed = 0;
}
public int getDrinksRemaining() {
return drinksStocked - drinksDispensed;
}
}
We don't want the value of drinksDispensed to change except when dispenseDrink() or stockDrinks(int numberOfDrinks) is called. It still needs to be able to be reassigned by it's own class when the vending machine is refilled though, so we shouldn't make it final
With respect to using public final, generally in Java that's only done for constants and that static keyword is also included since constants shouldn't be dependent on an instance.
An example of when it makes sense to use public static final
public class UnitConversions {
public static final double CENTIMETERS_PER_INCH = 2.54;
}
It could then be used in a method as follows
public double convertFromCentimetersToInches(double centimeters) {
return centimeters / UnitConversions.CENTIMETERS_PER_INCH;
}
Best of luck OP and happy coding.
More reading on final fields
This depends on some factors.
If this is a real constant that is known before and will never change, then use final. In Java final fields can be initialized in the constructor as well, so if your value is known at construction time then you can use final too.
If this value gets set (once, multiple times) during runtime then use private + getter.
The final modifier allows a field to be assigned only once - it cannot be changed after that and it has to be set at during object construction (that is, before the constructor returns).
If you want to make the field read-only, use the principles of information hiding: make it private and provide a public getter that returns the field (or a copy of it for non-primitive types).
You should use public final only for true constants. Even if your field is immutable because of final it is often a good idea to still make it private.
The correct way is to think in the future. What would help you achieve your goals? Maybe later you would also like to give that variable a value. If I were you, I'd do this by creatin a get method and keeping the variable private.
Full documentation for final keyword : http://en.wikipedia.org/wiki/Final_(Java)
Depends on where you want to access it from. Public variables can be accessed from any class within the project and package where private can only be accessed from the class where the variable is.
The 'final' operator makes it permanent and read-only.
Let's assume that type is a reference to an object, not a primitive type.
public final type attribute_name means that attribute_name cannot be reassigned to refer to something else. But attribute_name can be used to call a method that changes its state.
In private type attribute_name, only methods within the class can call methods on attribute_name.
So if you want it to remain constant, use approach (2). Limit the public methods to ones that ultimately call methods on attribute_name that don't modify its state.
fairly new to this language. Long time lurker, first time question asker.
In my program, I load a bunch of strings from a text file and then pass all of that information inside of a String array to a program that takes the data point by point (it comes in a reliable pattern) and assigns it to variables inside a class.
I use this loop to create the objects.
Gladiator[] gladiator = new Gladiator[(match.contestants)];
for ( int a = 0; a < match.contestants; a++) {
gladiator[a] = new Gladiator();
gladiator[a].populategladiators(parsedInfo,a);
}
Gladiator class full of public final variables which are defined in the method populategladiators. The syntax is as follows:
this.name = parsedInfo[0+mod][0];
this.culture = parsedInfo[1+mod][0];
this.background = parsedInfo[2+mod][0];
etc.
At the moment, I only load two gladiators and it seems like maybe both are being set at once with both pass throughs? Anyone have any thoughts on this?
Also, in another method in class Gladiator, should I be able to call this.name and be okay to get data about the object I specified when calling the method?
Edit: Trying to make the code look right. Giving up since there isn't much.
2nd Edit: Example of variable declaration in gladiator class:
public static String name;
public static String culture;
public static String background;
I had my variables set as static, thus it wasn't allowing me to set individual variables for the objects. I just didn't understand what the static keyword meant.
Ok my problem isnt really a serious one, im just trying to find a clever way of access/modification of class member variables. Here is the code:
public class Storage{
private int cookies= 0;
private int rolls= 0;
private int candies= 0;
private int lolipops= 0;
private int iceCreams= 0;
public void addCookies(int howMuch){ //this is the dirty way of creating method for
this.cookies = cookies+howMuch; //every member variable
}
public void addValue(String stat, int howMuch){ //i would like to do it only
//by passing the name
//of variable and then cast it as integer
//so that it would relate to my class members
int value = this.(Integer.parseInt(stat)); // <- YES i know its ridiculous
//im just trying to explain what is my aim
value = value + howMuch;
this.(Integer.parseInt(stat)) = value;
}
}
Generally i would like to access a field by passing its name to a method, read value of that member, add to it some value, and then store it. Yes i know that it easily can be done with separate methods, or even with one by using some arraylist and comparisons of member names with parameter passed to method. But i would like to do it "fast" without redundant code writing.
Now i have like 5 members, but what about 15000? My aim is to simplify the whole processing and code writing. So generally is it possible to do such redundant code writing bypass? Since i know that i will always pass appropriate name to method... Unless the rule of thumb is to create method for each variable?
Normally you would use a collection like a Map.
public class Storage{
private final Map<String, Integer> inventory = ...
public void addCount(String key, int count) {
Integer i = inventory.get(key);
if (i == null) i = 0;
inventory.put(key, i + count);
}
I guess that by using reflection you can iterate through the fields/methods of your object and do your computation.
For one specific field:
Field member = myObject.getClass().getField(fieldName);
// If you know the class: Field member = MyClass.class.getField(fieldName);
System.out.println(member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
If you want to something for all the public members:
for(Field member: myObject.getClass().getFields())
// Or you can do: for(Field member: myClass.class.getFields())
{
member.getInt(myObject)); // Get the value
member.setInt(myObject, 4); // Set the value
}
Basically, what you do is that you find the Field object that represents the members of you object, then you can manipulate it.
Most IDEs will generate setters and getters for you. This will do what you want with no bother or effort. If this is insufficient, write a method which uses reflection to set the values.
If you have a class with 15000 members, and by this I assume you mean variables private to a class, then you have other issues to resolve.