Handling object data in Java - java

Suppose I have a file like this:
Account1 +200
Account2 Holder:John
Account3 -200
Account2 -100
and so on.
I want to be able to query for example "Account1" for money. The Account names can be arbitrary in the text file. How should I go about doing this in Java? I know this sounds suspiciously derpish but for the life of me I can't figure out a way that seems right.
The obvious idea would be to make an ArrayList with objects of type "Account". However then every time you wanted to check an account, you'd have to go through every single item of the ArrayList and carry out getName() to check if it's equal to it, which seems very labour intensive for simply bringing up an object. Is there any way you could somehow convert between string/data and object handles since Java is an interpretive language?

An obvious solution is to use a HashMap<String, Account> map.
check this: https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Then to get Account1 you do: map.get("Account1");

Related

How to get cumulative amount total from list of Map

In one of my case I get the input like below which has a list inside with list of Maps.
List<Map<String, String>> actAllSavAccDetLists = test1Page.getAllSavingsAccountsDetails();
// returns like this
[
{Savings=Account ****2623, Current Balance=$22000.00, Annual Rate=7.77%, Transfer=Make a Transfer, Ellipses=...},
{Savings=Account ****5678, Current Balance=$11000.00, Annual Rate=2.22%, Transfer=Make a Transfer, Ellipses=...}
]
Now I need to find the total balance for the user, i.e.; adding up all the current balance from the Map inside a list.
Say in this case, adding $22000.00 + $11000.00 to give the result as $33000.00 in a total_bal variable.
You can easily use java stream map->reduce to make that:
Double totalBalance = actAllSavAccDetLists.stream()
.map(e -> e.get("Current Balance").substring(1))
.map(e -> new BigDecimal(e))
.reduce(BigDecimal.ZERO, BigDecimal::add);
The java-compatible way to do it is not to have this map at all. Java is nominally typed, and really likes its types. a Map<String, String> is not an appropriate data type here.
First, make a class that represents a savings account.
Next, instead of having a List<Map<String, String>>, have a List<SavingsAccount>.
Finally, sum up the balances.
Making a class
Looks like it would be something along the lines of:
#lombok.Value
public class SavingsAccount {
String accountId;
int balance; // in cents
double rate; // might need to be BigDecimal
}
You'll need to festoon it up to become a proper java class (the fields need to be final and private, getters and setters nee dto be there, a constructor, equals, toString, etcetera). I'm using lombok here (disclaimer: I'm one of the developers), but you can also use a java16 record, or use your IDE to generate all this stuff.
Converting that mess into instances of SavingsAccount
Converting a map that contains for example a mapping Transfer = Make a Transfer into an instance of this rather strongly suggests your input is coming from some bizarre source. You'll know better than we do how to convert it. You can now localize all the various required conversions and open questions into a single place. For example, what should happen if, say, map.get("CurrentBalance") doesn't exist, or returns "€10000.00"?
This boils down to "How do I convert the string "$22000.00" into the integer 2200000", or "How do I convert "7.77%" into a double", which is not difficult, and an unrelated question; if you're having trouble with it, I'm sure it's been answered a million times on SO already so you'll find it swiftly with a web search.
Summing it up
That's trivial:
List<SavingsAccount> accounts = ...;
int sum = accounts.stream().mapToInt(SavingsAccount::getBalance).sum();
This streams all the accounts, extracts just the balance from each, and then sums the entire stream into a single number.
I don't want to make that class
Well, it's a bit silly to do things in ways no sane java programmer would ever do. If you're trying to learn, you'll be learning the wrong ways of work. If you're trying to deliver freelance work, you'll get negative reviews. If you're "in a hurry", taking shortcuts now will just cost you triple later on. You do want to make that class.
If you insist on being stubborn, the same techniques can be used, just, with the order all jumbled up. You can stick the code that extracts the balance in that mapToInt call:
.mapToInt(s -> extractBalanceFromThisBizarroMap(s))
and then just write static int extractBalanceFromThisBizarroMap(Map<String, String> s) yourself.
But don't do that.

Dynamic Named SQL Fields

So i've got a bot that serves as a roleplaying mamager handeling combat, skill points and the like, i'm trying to make my code a bit more general so i can have less pages since they all do the same thing they just have different initilizers but i ran into a snag i need to check if the user has a minimum in a particular stat Strength, perceptions, agility, etc
so i call
mainSPECIAL = rows[0].Strength;
Here's the rub, weathers it strength, percpetion, intelligence, luck, whatever i'm always going to be checking Rows[0].that attribute ie Rows[0].Luck for luck perks, and i already set earlier in my initilizers
var PERKSPECIALName = "Strength";
But i can't call
mainSPECIAL = rows[0].PERKSPECIALName but there should be a way to do that right? so that when it sees "rows[0].PERKSPECIALName" it looks up "PERKSPECIALName" and then fetches the value of rows[0].Strength
For this you need to use reflection:
Field f1 = rows[0].getClass().getField(PERKSPECIALName);
Integer attribute = (Integer) f1.get(rows[0]);
Where "Integer" is the type of the element your pulling from the object (the type of strength)
The field must be declared as public! I think there is a way to obtain them when they are not public but it requires more code.
Seems like you have a set of integers that you need to identify with a constant identifier. You might find an EnumMap useful. Have a look at How to use enumMap in java.
Or if you want to only use a string to identify which perk you want to reference, just use a Map.
Java doesn't have reference-to-member like some other languages, so if you don't want to change your data structure, you are looking at using lambda functions or heavier language features to increase re-use, which seems like overkill for what you're trying to do.

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.

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