I am looking for a way to reduce the castings of properties from java Properties to Numeric such as Integer, Double and if possible even a class that might casting directly for instance Integer[].
Say I have multiple properties and must pass for instantiation many times and I wish to use a class that parses and casts only once.
Properties mogaProps = parseProperties("mogabcpu/moga");
for (int i=0;i<10000;i++){
NSGA2Runner GA = new NSGA2Runner(Integer.valueOf(mogaProps.getProperty(
"NUMINITIALCHROMOSSOMES")), Integer.valueOf(mogaProps.getProperty(
"NUMCHROMOSOMES")),
Double.valueOf(mogaProps.getProperty(
"MUTATIONRATE")), Double.valueOf(mogaProps.getProperty(
"CROSSOVERRATE")),
parseStringTo1DArray(mogaProps.getProperty("NUMITERATIONS"))
}
Is there a better alternative avoiding the use of a custom class to specifically hold all potential different data types attributes?
I have found this However I could not find this Config Class dependency.
Thanks
I am looking for a way to reduce the castings of properties
You are parsing, not casting. The .valueOf calls are creating new values by interpreting the meaning held within text (parsing) rather than reshaping an existing value (casting). But not a useful distinction in the context of your Question, just FYI.
Say I have multiple properties and must pass for instantiation many times and I wish to use a class that parses and casts only once.
If the properties are not changing at runtime, just instantiate your configuration object (a NSGA2Runner object in your case, your GA) once. Pass that object around to the other methods and objects that need the information.
In your example code with the for loop, if your real code is processing the properties once and then using that data 10,000 times, move your GA = line to outside the loop.
By the way, if you are assigning an object once only, mark GA as final. That keyword obstructs any inadvertent attempt to make that variable point to any other object.
reduce the castings of properties from java Properties to Numeric such as Integer, Double
Your data is stored as text in a Properties. You need to work with that data as numbers, not text. So there is no getting around the chore of parsing that text into numbers.
I am not sure why you are concerned about this. Perhaps performance is your concern? Such parsing is quick and easy. Not a significant impact on performance unless you are often processing millions of such values. Do a bit of micro benchmarking to see for yourself.
Is there a better alternative avoiding the use of a custom class to specifically hold all potential different data types attributes?
Defining a class is the appropriate way to gather together related parts of information in an object-oriented language like Java.
If your data is read-only, then you might want to use the records feature in Java 16 and later. A record is a brief way to write a class whose main purpose is to communicate data transparently and immutably. You merely need to declare the type and name of each member field. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.
public record NSGA2Runner( int numberOfInitialChromosomes , int numberOfChromosomes , double mutationRate , double crossoverRate , int[] numberOfIterations ) {}
Related
First post so I hope this is an appropriate type question for this site. If not I'd appreciate it if someone could direct me to a more appropriate place. I'm extremely new at programming. I did a bit in high school and have recently decided to relearn starting with making a text-based survival game in Java7 using Eclipse.
Right now I'm coding the location superclass. The particular function I need help with is this: it needs to be able to keep track of which of 9 regions the user currently "is in" (which is then used in a large number of other classes for many various purposes. The location class also includes functionality for accepting user input to move to a new region, among various other things.) The way I started this was by making a boolean variable for each region and whenever a transition should occur that variable is set to true. But now I'm wondering if this is the most efficient way to do this. I have to take String inputs, run a method to standardize various acceptable answers into one, and then run it through a switch statement that makes the corresponding boolean variable true?
Would it be simpler to simply keep track of the location with a single String variable that gets set as whatever region the player is in? Or would that be more likely to cause errors or complications when coding? Would an array better suit this need? edit: (I just want to thank you guys for people such an open and helpful community. Its really appreciated.)
BIG EDIT: I wanted to further elaborate on what the regions will eventually do. In each region there will eventually be a handful of places the user can go to that are generic with a small number of places unique to each location. Other major superclasses would be altered depending on what region the user is in (example: my "encounters" superclass would have variables that dictate how likely certain encounters are to happen (i.e. chance to a hostile attack) and these variables would be altered depending on the region) but also by other instances (The "Time" superclass would keep track of the day and time of day which would also effect the variables in "encounters".) The current plan was to make a class for each generic place (i.e. Walmart, technology store, grocery, public park, etc.) They would contain different properties depending on the region and would also effect classes like "encounters". I was going to have their properties defined by if/else & switch statements depending on what region the user was in. But now I'm realizing it would make more sense to define their properties when I create the object.
While a lot of people are steering me to enums, some are also suggesting I make classes for each region, (and I am also hearing about interfaces.) If I were to go with the 2nd route I have 3 questions: (a) If the region classes were all subclasses to "Location", then wouldn't I have a problem creating objects for all the generic places inside the region classes (i.e. Walmarts) because the Walmart class can only belong to one superclass? (If not what is the difference between an object being created in a class and the actual relationship between a superclass and its subclasses) (b) If I initialized each region as an object instead of simply recording it with a variable, how would I achieve the original task of remembering which region the user is in (for functions as simple as printing the region out to making alterations to variables in classes like "encounters"). Wouldn't I still need to have some sort of variable to identify the region? And if so, that what practical purpose does creating classes for the region accomplish? (I can see this might still let me make the code cleaner by housing the variables that interact with "encounters" instead of having to use if/else/switch statements inside the "encounters" class (also in this case how could I make the variables in the region classes interact with the variables in "encounters" since neither belong to each other) but anything else?) (c) Would it make more sense to create classes for every region or a single region class that gets defined differently when initialized and WHY?
Finally, I know I may have asked too many questions but could someone please explain to me the different utilities found in enums and interfaces (I'm especially interested in hearing about enums) and now that you know a little bit more, should I be using enums, interfaces, or some sort of classes for the regions? Thank you guys so much!
Enum is very recommended, as stated by Vasily Liaskovsky.
Using int is a great way as well. For example:
int currentRegion;
static final int region1 = 0;
static final int region2 = 1;
static final int region3 = 2;
etc...
Make sure the region1 etc are stated final, so their IDs cannot be changed afterwards, static reference could save memory if you're using multiple location superclass objects, also easier accessible outside the class.
This way to check if you're in a certain region, just use a if statement:
if(currentRegion == region1) {}
To set it:
currentRegion = region1;
Simple as that
I disagree with the usage of an enum here. An enum is great, but not extendable. What if you want to add another region?
So just create classes, and pass them around. They might hold some form of string as identifier (but you should load the proper name from a file that can be localized, anyways).
With a proper class, you can easily add new transitions betwen regions (make your region class a graph) and much more.
Region current = ...;
List<Transition> neighbours = current.getNeighbours();
foreach (Transition t : neighbours)
System.out.println("To the " + transition.getDirection() + " is the " + transition.getTargetName());
// prints e.g. "To the north is the shadowy jungle"
There are a lot of ways todo this, and in an OOP language, you should really try to get into the mindset of using objects instead of setting integer flags or else.
Take a look on enum.
If the list of 9 regions should not grow as game develops, you can describe each of them in hardcoded fashion also utilizing power of objects. Enums can have custom properties and methods weawing them into your architecture, and also enums provide some extra benefits such as == comparison and using in switch blocks.
EDIT
I don't understand why this future addition might make enums a less desirable route
The only way to add an option to enum is to rewrite its class source code. That is, enum options are defined statically and in larger projects when developers should deal with product versions, compatibility, delivering to end-users etc., this could be a pain. In fact, any change in source code of published project is undesirable, since it requires recompilation and full rebuild of at least one (in best case) application module.
The way to deal with it is to move modifiable data into some resource (this can be a file, database table, plugin or anything easily modifiable without full rebuild) and make your application to initialize itself on startup in runtime. Since from this point your program no longer knows that data in advance, statically, there is no way you could define enum describing that data. And in this scenario custom classes (Polygnome's answer) will do the job. Your program reads the resource, creates and initializes objects in runtime that describe your configuration and uses dynamic data.
IMHO, there is almost always tradeoff beween flexibility and complexity. You gain flexibility and freedom to modify region list, but you have to deal with complexity of dynamic solution. Or you decide to use much simpler enums understanding their limited extensibility.
Btw, in order of growing flexibility (and complexity):
raw primitives (int/String) | enums | custom classes
I'm heavily using Java.lang.Class.getField() method which requires a String variable as an argument. The problem I'm facing is when I change field names, that getField() refers to, Eclipse doesn't warn me that argument points nowhere (since it's String) and I end up having methods working improperly unnoticed.
So far I can see two ways out. It's either using try-catch blocks around every getField() call and running application to see what will be the next line to throw an exception. Fix it and watch out for the next exception. Or it's using Find/Replace feature every time I change a field name to manually look for the String value and replace it. Is there a more friendly (i.e. automatic) way to update String parameters in such cases?
Maybe there's a method (which I fail to find) that accepts a full field path as a non-String argument and returns a Field object? Something like turnToFieldObject(car.speed) returning Field object corresponding to speed field so that Eclipse would automatically check if there's such a field car.speed.
PS
First of all, thank you for your replies.
I can see that a lot of you, guys, suggest that I'm using reflection too much. That's why I feel I need to add extra explanation and would be glad to hear suggestions as well.
I'm doing a research about modeling social evolution and I need the entities to evolve new features that they don't have at the start. And it seemed to me that adding new fields to represent some evolutional changes is better understanding wise than adding new elements to arrays or collections. And the task suggests I shouldn't be able to know what feature will be evolved. That's why I rely so heavily on reflection.
AFAIK, there is no such method. You pass a reference (if it's an object) or value (if it's primitive); all data about the variables that they were originally assigned to is not available at runtime.
This is the huge downside of using reflection, and if you're "heavily" using this feature in such way, you're probably doing something wrong. Why not access the field directly, using getters and setters?
Don't get me wrong, reflection has its uses (for example, when you want to scan for fields with certain annotations and inject their values), but if you're referencing fields or methods by their name using a simple string, you could just as well access fields or methods directly. It implies that you know the field beforehand. If it's private, there is probably a reason why it's encapsulated. You're losing the content assist and refactoring possibilities by overusing reflection.
If you're modeling social evolution, I'd go with a more flexible solution. Adding new fields at runtime is (near?) impossible, so you are basically forced to implement a new class for each entity and create a new object each time the entity "evolves". That's why I suggest you to go with one of these solutions:
Use Map<String, Object> to store entities' properties. This is a very flexible solution which will allow you easily add and remove "fields" at the cost of losing their type data. Checking if the entity has a certain property will be a cheap contains call.
If you really want to stick to a million custom classes, use interfaces with getters and setters in addition to fields. For example, convert private String name to interface Named { String getName(); void setName(String name); }. This is much easier to refactor and does not rely on reflection. A class can implement as many interfaces as you want, so this is pretty much like the field solution, except it allows you to create custom getters/setters with extra logic if desperately needed. And determining if entity has a certain property is a entity instanceof MyInterface call, which is still cheaper than reflection.
I would suggest writing a method that use to get your fields supply it a string and then if the exception is thrown notify whatever needs to be notified that it was not valid and if the exception isn't caught return the field.
Although I do agree with the above that reflection should not be used heavily.
Assuming we have an object inside an object, inside another object, what is the best way to retrieve the value of a private variable outside the two objects?
The simplest way seems to be to do something like this:
object1.object2.object3.getvalue();
Is this acceptable? Or would it be better to call a method which calls a method, which calls a method?
The second option seems unnecessarily laborious, considering you would basically be having the same method created in 3 different classes.
use getter to get any object
ex: Object obj = object1.getObject2().getObject3();
It depends on your definition of "acceptable". It may be acceptable in your case. It is hard to tell without proper context.
However, there are something you may consider, level-by-level:
1. Use of getters
Although such kind of getters are still far from satisfactory, it is still better than using direct property access
i.e. Instead of accessing object1.object2 by direct field access, provide Object2 getObject2() in Object1, so that the code looks like:
object1.getObject2().getObject3().getValue()
2. Null handling
Usually when we chained such kind of property navigation, we will have problem that in some level, null is returned, which makes object1.getObject2().getObject3().getValue() throwing NPE.
If you are using Java 8, consider returning Optional<>. e.g. in Object1, getter of object2 should look like Optional<Object2> getObject2()
With such change, your code can be made null-safe by something like:
Value value = object1.getObject2()
.flatMap(Object2::getObject3)
.map(Object3::getValue)
.orElse(Value.emptyValue())
3. Law of Demeter
In order to make a more loosely-coupled design, you may want to provide access to that value in API of Object1, instead of exposing multiple levels of indirection. Hence:
Value value = object1.getFooValue();
(Keep using Optional<> if it fit your need)
for which internally it retrieve the value from Object3. (Of course, Object2 may also want to do something similar)
4. Getter is evil
Always remember you should try to avoid providing internal representation of your object. Your objects should provide meaningful behavior instead of simply act as a value object for you to get or set data. It is hard to give an example here but ask yourself, why do you need to get the value for? Is that action more appropriate to be provided by your object itself?
The best way is to not think of your objects as data stores. A class should be defined to have some work to do, some cluster of related responsibilities. In order to perform that work to fulfill those responsibilities some internal data may be kept, and some nested objects contained. Serving out data should not be the goal of your objects, generally speaking.
Encapsulation
The whole idea of encapsulation in object-oriented programming is to not expose that internal data and nested objects. Instead publish the various available chores by declaring methods on your higher/outer object. Encapsulation frees you to change those internals without breaking the outside calling code – avoiding fragility is the goal.
For example, an Invoice object can contain a collection of LineItem objects. In turn each LineItem object contains other objects for product, quantity, price, extended cost, taxability, tax rate, tax amount, and line cost. If you want to know the total amount of sales tax added across the items, instead of asking the Invoice for the LineItem, and then asking the LineItem for TaxAmount object, define this chore as a method on Invoice, getTotalTaxAmount. Let that method figure out (and keep to itself!) how to go through the contained objects to collect the relevant information.
If you absolutely must expose that nested data, again define a method at the highest level that returns a copy of the desired data or a collection of the desired objects (probably copies of those objects). Again, the goal is to avoid exposing the objects within objects within objects.
Then, within that highest method, as the correct Answer by Raaga stated, define a getter that calls a getter.
Getter Methods versus Direct Member Access
In a very simple structure of data you could access the objects directly. But generally better to use getter methods. Again the reason is encapsulation. Having a getter method allows you the flexibility of redefining the implementation details of the stored data.
For example, presently you could store the "Sex" variable as a String with values of "F" or "M". But later you may decide to take advantage of Java's nifty enum feature. So you replace those single-character "F" & "M" strings with enum instances Sex.FEMALE and Sex.MALE. Having a getter provides a level of insulation, so the Strings can be replaced internally with enums. The getter method continues to return a String (and internally translating the enum to an "F" or "M" String to be returned). This way you can work on restructuring your class without breaking those dependent outside objects.
object1.object2.object3.getvalue();
This chaining seems incorrect...Object chaining under such scenario is always object1.someMethod().someOtherMethod(). Or something like suggested above in an answer using getter object1.getObject2().getObject3().
I hope it helps.
What you described may be the simplest way (if object2 and object3 are accessible) but it is definitely not the way to go. As Raaga pointed out getters are a lot better to retrieve members of a class and these members should then be private or protected to prevent errors.
If you can do
object1.object2.object3.getvalue();
you can also do something like
object1.object2 = null;
which is most likely not what you want to allow. This is one of the basic concepts of object oriented programming. Classes should handle their implementation details / secrets and not directly offer them to the outside! This is what getters/setters are for.
This way you have more control over the access and what can be done and what can't. If you should only be able to retrieve object2 from object1 but not be able to change it, you can only offer a getter and no setter.
If you should also be able to change it, it is also better to use setter for more control, because you can do checking in your setter to prevent my example where I put a null pointer as your object2
And just in case you worry about efficiency that calling a method might not be as efficient as directly accessing a member, you can rely on Java to internally optimize your method call that it is not any slower than the direct access.
I have a (java) class with about 10 attributes, many of them potentially staying uninitialized and are not accessed during lifetime of an object.
Therefore I'm considering using a Map<String,Object> as an attribute-name -> attribute-value map instead of a lot of fields, in order to save resources.
Now I am wondering, if there exist any offical or unofficial rules, when and how to decide on one of the described possibilities. How many attributes should a class have, before I should consider using such a map? Should I use it at all?
Thanks in advance for your advice/opinions on that.
Okay so you're doing this to save memory I assume because clearly you're not saving CPU resources by accessing a map instead of a field. So let's see how good that works out: (assuming 64bit JVM without compressed oops - which is unrealistically but shouldn't change the results too much, you can compute it yourself easily)
Basically a field in java will never take up more than 8bytes (well word size for references). So this means for your class with 10 fields, assuming all are unused the best we can save are 8*10 bytes = 80byte.
Now you want to replace this with one HashMap instead - that means we already use up 8 extra bytes for that. Also the HashMap is always initialized so we get the overhead of: 2 words header + reference + 3 ints + float + 1 array (2 words overhead, 4byte size, 16 references by default) which takes up 182 bytes of memory.
May I congratulate you to saving a whopping -110 bytes!
PS: I think the smallest possible default value for the backing array of the hashset is 2, so you could use that and come out about even. But as soon as you store objects in the set, you get additional overhead from the Wrapper objects used by the class. So really it's a bad idea.
It's not about how many different attributes you have it's about how they are used and what is needed. A Map will allow for more flexibility to not have attributes or to have different attributes for different instances or add attributes later (through adding things to the Map). But if the attributes are different types String, Integer, Doubles etc this will require making the Map of type Object and casting all the values when you use them (a lot more work for you).
I don't think Map is a good idea.
from OO point of view, fields are properties of a Type and its subType. think about inheritance and polymorphism, how can you make the Map achieve those characters of OO?
even if talking about code style, this is not making your codes cleaner. How do you handle type casting? exception handling? those codes would be much more than the field declaration and getter/setters (if you have them)
I like the Map idea for attributes which are truly optional and "non-essential". Otherwise you'll need a whole bunch of subclasses and/or you always need to check for null in your getters.
As for the typing, I often write code passing in the default value as the 2nd argument, and use it to determine the return type. e.g.
int getValue(String key, int defaultValue);
double getValue(String key, double defaultValue);
String getValue(String key, String defaultValue);
The caller, not the Map, has to know the type. YMMV whether you like this style...
However, for attributes which are "essential", I prefer real fields.
On the very high level, I know that we need to "wrap" the primitive data types, such as int and char, by using their respective wrapper classes to use them within Java collections.I would like to understand how Java collections work at the low level by asking:"why do we need to wrap primitive data types as objects to be able to use them in collections?"I thank you in advance for your help.
Because Java collections can only store Object References (so you need to box primitives to store them in collections).
Read this short article on Autoboxing for more info.
If you want the nitty gritty details, it pretty much boils down to the following:
Local Primitives are stored on the Stack. Collections store their values via a reference to an Object's memory location in the Heap. To get that reference for a local primitive, you have to box (take the value on the Stack and wrap it for storage on the Heap) the value.
At the virtual machine level, it's because primitive types are represented very differently in memory compared to reference types like java.lang.Object and its derived types. Primitive int in Java for example is just 4 bytes in memory, whereas an Object takes up at minimum 8 bytes by itself, plus another 4 bytes for referencing it. Such design is a simple reflection of the fact that CPUs can treat primitive types much more efficiently.
So one answer to your question "why wrapper types are needed" is because of performance improvement that it enables.
But for programmers, such distinction adds some undesirable cognitive overhead (e.g., can't use int and float in collections.) In fact, it's quite possible to do a language design by hiding that distinction --- many scripting languages do this, and CLR does that. Starting 1.5, Java does that, too. This is achieved by letting the compiler silently insert necessary conversion between primitive representation and Object representation (which is commonly referred to as boxing/unboxing.)
So another answer to your question is, "no, we don't need it", because the compiler does that automatically for you, and to certain extent you can forget what's going on behind the scene.
Read all of the answers, but none of them really explains it simply in layman terms.
A wrapper class wraps(encloses) around a data type (can be any primitive data type such as int, char, byte, long) and makes it an object.
Here are a few reasons why wrapper classes are needed:
Allows null values.
Can be used in collection such as List, Map, etc.
Can be used in methods which accepts arguments of Object type.
Can be created like Objects using new ClassName() like other objects:
Integer wrapperInt = new Integer("10");
Makes available all the functions that Object class has such as clone(), equals(), hashCode(), toString() etc.
Wrapper classes can be created in two ways:
Using constructor:
Integer i = new Integer("1"); //new object is created
Using valueOf() static method:
Integer i = Integer.valueOf("100"); //100 is stored in variable
It is advised to use the second way of creating wrapper classes as it takes less memory as a new object is not created.
To store the Primitive type values in Collection. We require Wrapper classes.
Primitive data types can't be referenced as memory addresses. That's why we need wrappers which serve as placeholders for primitive values. These values then can be mutated and accessed, reorganized, sorted or randomized.
Collection uses Generics as the bases. The Collection Framework is designed to collect, store and manipulate the data of any class. So it uses generic type. By using Generics it is capable of storing the data of ANY CLASS whose name you specify in its declaration.
Now we have various scenario in which want to store the primitive data in the same manner in which the collection works. We have no way to store primitive data using Collection classes like ArrayList, HashSet etc because Collection classes can store objects only. So for storing primitive types in Collection we are provided with wrapper classes.
Edit:
Another benefit of having wrapper classes is that absence of an object can be treated as "no data". In case of primitive, you will always have a value.
Say we have method signature as
public void foo(String aString, int aNumber)
you can't make aNumber as optional in above method signature.
But if you make signature like:
public void foo(String aString, Integer aNumber)
you have now made aNumber as optional since user can pass null as a value.
See Boxing and unboxing: when does it come up?
It's for C#, but the same concept apply to Java. And John Skeet wrote the answer.
Well, the reason is because Java collections doesn't differentiate between primitive and Object. It processes them all as Object and therefore, it will need a wrapper. You can easily build your own collection class that doesn't need wrapper, but at the end, you will have to build one for each type char, int, float, double, etc multiply by the types of the collections (Set, Map, List, + their implementation).
Can you imagine how boring that is?
And the fact is, the performance it brings by using no wrapper is almost negligible for most applications. Yet if you need very high performance, some libraries for primitive collections are also available (e.g. http://www.joda.org/joda-primitives/)
Wrapper classes provide useful methods related to corresponding data types which you can make use of in certain cases.
One simple example. Consider this,
Integer x=new Integer(10);
//to get the byte value of 10
x.byteValue();
//but you can't do this,
int x=10;
x.byteValue(); //Wrong!
can you get the point?
If a variable is known to either hold a specific bit pattern representing null or else information which can be used to locate a Java Virtual Machine object header, and if the method for reading an object header given a reference will inherently trap if given the bit pattern associated with null, then the JVM can access the object identified by the variable on the assumption that there is one. If a variable could hold something which wasn't a valid reference but wasn't the specific null bit pattern, any code which tried to use that variable would have to first check whether it identified an object. That would greatly slow down the JVM.
If Object derived from Anything, and class objects derived from Object, but primitives inherited from a different class derived from Anything, then in a 64-bit implementation it might be practical to say that about 3/4 of the possible bit patterns would represent double values below 2^512, 1/8 of them to represent long values in the range +/- 1,152,921,504,606,846,975, a few billion to represent any possible value of any other primitve, and the 1/256 to identify objects. Many kinds of operations on things of type Anything would be slower than with type Object, but such operations would not be terribly frequent; most code would end up casting Anything to some more specific type before trying to work with it; the actual type stored in the Anything would need to be checked before the cast, but not after the cast was performed. Absent a distinction between a variable holding a reference to a heap type, however, versus one holding "anything", there would be no way to avoid having the overhead extend considerably further than it otherwise would or should.
Much like the String class, Wrappers provide added functionality and enable the programmer to do a bit more with the process of data storage. So in the same way people use the String class like....
String uglyString = "fUbAr";
String myStr = uglyString.toLower();
so too, they can with the Wrapper. Similar idea.
This is in addition to the typing issue of collections/generics mentioned above by Bharat.
because int does not belongs any class .
we convert datatype(int) to object(Interger)