Assign values to numerically-named variable from an arraylist - java

The legacy code i'm working on uses 21 numerically-named attributes for a class, for 3 differents things (lets call them "firstThing", "secondThing", and "thirdThing").
So I have the firstThing1, firstThing2, ... firstThing7 attributes in my class, and the same for secondThing and thirdThing.
Everywhere in the code where objects of that class are used, it's just pieces of code copied 7 times that all do the same thing, beside of using the correct numerically-named attribute. Not so great.
Instead of changing the whole picture and redesigning the class, i wanted to at least change the functions i'm working on : doing a loop with the redundant code, add the values to a specific ArrayList where they were previously assigned. Now I would know if there is a way to take all those values from my ArrayList, and assign them to the specific numerically-named attribute ? Or a way to test the length of the differents ArrayList and assign values to that many number of attributes ? Or should I just copy
if(listOfFirstThings.size() >= 1)
myObject.setFirstThing1(listOfFirstThings.get(0));
if(listOfFirstThings.size() >= 2)
myObject.setFirstThing2(listOfFirstThings.get(1));
...
21 times to assign everything I need ?

Redesigning the class is the way to go. You've effectively got three collections - which should quite possibly be one collection, with each element having three properties.
Java just isn't designed to use execution-time-generated variable names. You can do it with reflection, but I would strongly encourage you to fix it properly right now. (I'd actually do this as a refactoring step before trying to add whatever new feature you're working on.)

Related

How to store null elements in some object array and to know they are stored intentionally(not generated by java)

I am creating ExpandableArray class what contains Product classes inside.
I have method add(Product p) that adds Product in first null position in my ExpandableArray.
And method replace(index int, Product p) - replaces product with this index by with p.
i have confronted following situation:
ExpandableArray expArr = new ExpandableArray(3); // let initial size be 3 products.
expArr.add(p1);
expArr.add(p2);
expArr.replace(0,null) // [null,p2,null].
notice that i replaced first element by null intentionally! method add shouldn't touch it, it should work with the second null.
But how do i do that?
My solution is to make integer[]intentionedNullIndexes array inside ExpandableArray, and it will contain all indexes will intentioned nulls. so method add firstly will check if this null index is in intentionedNullIndexes and if it is he won't touch it.
i don't like this solution because it's hard to implement and wastes MANY RAM. Any suggestions?
Your requirement is an XY-problem.
It's an antipattern when null has some kind of special meaning in your business logic. The only valid meaning of null - is no data (otherwise the code becomes muddy).
i don't like this solution because it's hard to implement and wastes MANY RAM
There's no need to waste lots of memory. You need only one reference to a placeholder object, which you can use as many times as you need.

Is there a Parameter Tree implementation in Java?

Java program takes a long list of inputs(parameters), churns a bit and spits some output.
I need a way to organize these parameters in a sane way so in the input txt file I want to write them like this:
parameter1 = 12
parameter2 = 10
strategy1.parameter1 = "goofy"
strategy2.parameter4 = 100.0
Then read this txt file, turn it into a Java object I can pass around to objects when I instantiate them.
I now pyqtgraph has ParameterTree which is handy to use; is there something similar in Java? I am sure others must have had the same need so I don't want to reinvent the wheel.
(other tree structures would also be fine, of course, I just wanted something easy to read)
One way is to turn input.txt into input.json:
{
"parameter1": 12,
"parameter2": 10,
"strategy1": {
"parameter1": "goofy"
},
"strategy2": {
"parameter4": 100.0
}
}
Then use Jackson to deserialize input.json into one of these:
A Map<String, Object> instance, which you could navigate in depth to get all your parameters
An instance of some class of your own that mimics input.json's structure, where your parameters would reside
A JsonNode instance that would be the root of the tree
(1) has the advantage that it's easy and you don't have to create any class to read the parameters, however you'd need to traverse the map, downcast the values you get from it, and you'd need to know the keys in advance (keys match json object's attribute names).
(2) has the advantage that everything would be correctly typed upon deserialization; no need to downcast anything, since every type would be a field of your own classes which represent the structure of the parameters. However, if the structure of your input.json file changed, you would need to change the structure of your classes as well.
(3) is the most flexible of all, and I believe it's the option that is closest to what you have in mind, nonetheless is the most tedious to work with, since it's too low-level. Please refer to this article for further details.

4 Key Value HashMap? Array? Best Approach?

I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.

2D Array that can hold multiple values with no limits

I am quite new to java currently working on a not-so-simple web browser application in which I would like to record a permanent history file with a 2D array setup with 3 columns containing "Date Viewed", "URL", "How many times this URL has been viewed before".
Currently I have a temporary solution that only saves "URL" which is also used for "Back, Foward" features using an ArrayList.
private List tempHistory = new ArrayList();
I am reading through the Java documentation but I cannot put together a solution, unless I am missing the obvious there is no 2D array as flexible a ArrayList like in Python?
From your description it doesn't sound like you need a 2D array. You just have one dimension -- but of complex data types, right?
So define a HistoryItem class or something with a Date property for date viewed, URL for URL, int for view count.
Then you just want a List<HistoryItem> history = new ArrayList<HistoryItem>().
The reason I don't think you really want a 2D array-like thing is that it could only hold one data type, and you clearly have several data types at work here, like a date and a count. But if you really want a table-like abstraction, try Guava's Table.
No, there is no built-in 2D array type in Java (unless you use primitive arrays).
You could just use a list of lists (List<List>) - however, I think it is almost always better to use a custom type that you put into the list. In your case, you'd create a class HistoryEntry (with fields for "Date viewed", URL etc.), and use List<HistoryEntry>. That way, you get all the benefits a proper type gives you (typechecking, completion in an IDE, ability to put methods into the class etc.).
How do you plan to browse the history then? If you want to search the history for each url later on then ArrayList approach might not be efficient.
I would rather prefer a Map with URL as key.
Map<Url,UrlHistory> browseHistory = new HahMap<Url,UrlHistory> ();
UrlHistory will contains all the fields you want to associate with a url like no. of times page was accessed and all.

New classes created by users?

Consider this situation: I've got an aquarium simulator where I have 5 different types of fishes. Different types means different attributes (speed, colour, hunger, etc). What if I want the user of my simulator to be able to create a new type of fish and give it its values for its attributes?
How is that implemented by the programmer? Do I need some kind of "event handling" that will add a specific bunch of lines of code in my "Fish" class? Is that even a valid thought?
(In case it's essential, the language is Java. And to avoid any misunderstandings and prevent comments like "is this uni work?", yes it is. But I am not looking for THE answer, I am curious about the concept.)
EDIT: Yeah, my bad that I didn't mention the interaction way: a GUI.
So, imagine a tab called "Add New Species" that has a field for every attribute of the fishes (type, speed, colour, etc). So, the user fills in the fields with the appropriate values and when he clicks on "add" the constructor is called. At least that's how I imagine it. :)
I would just use a map:
class Fish
{
Map<String,String> attributes = new HashMap<String,String>();
setBusterFish()
{
attributes.put("speed", "5");
attributes.put("colour", "red");
attributes.put("hunger", "10");
attributes.put("name", "buster");
}
}
Java is an OO language, and it deals in classes and objects. The tempting, naive solution would be to have your program deal with "classes" of fish like it deals with classes of anything, i.e. to create some Java code and let the compiler and loader introduce it into the runtime.
This approach can be made to work, with some awkwardness. Essentially your "dynamic Java classes" coding would probably end up much bigger and complicated than your assignment actually intends.
You only really need to do this if you are actually going to have different attributes (not just different values of those attributes) for your different fish; and even then there are simpler solutions.
For what's being asked, I think you really only need one Fish class. When the user defines a new one, what he's really defining are the attribute values.
If you really want new and dynamic attributes, then you could go a long way using e.g. a HashMap to store name/value pairs. You could let the user add "legs" / "4" and then print out that new attribute as-is; but you couldn't make the fish walk on those legs because you'd be missing coding to work with the new attribute.
Have a look at the type object pattern. Also google for it I just gave one of the first references I found...
You may also look the Reflection pattern...
Let the user define attribute values of an instance of, say, a FishSpecies class, and give the FishSpecies a method createFish that creates a fish of that species (i.e. having those attribute values). Keeping track of all FishSpecies objects in a list grants you the opportunity to manage FishSpecies objects, and create Fish objects of given species.
If I understand your question correctly, then I believe that complicating things more than this is a mistake.

Categories

Resources