I have an object Person with the following fields:
firstName, secondName, age, nationallity, address, phoneNr.
And the list: ['John', 'Smith', '35', 'american', 'San Francisco', '+0324 235 327'].
I would like to put the values of the list into the object Person, without using the classic method of setting each value.
I want to avoid this:
person.setFirstName(list.get(0));
person.setSecondName(list.get(1));
person.setAge(list.get(2));
person.setNationallity(list.get(3));
person.setAddress(list.get(4));
person.setPhoneNumber(list.get(5));
My object has more fields than the ones I've put here as example (about 15), and I want to avoid writting a lot of code.
So my question is there a more elegant way of dumping all the values from the list into the object? I was thinking that in Java 8 maybe is there something but so far I haven't found anything.
There is no way to dump all values from the list into object, but you can add a new contructor in your Person Class, with a list as parameter like this :
public Person(List<String> list) {
this.firstName(list.get(0));
this.secondName(list.get(1));
this.age(list.get(2));
this.nationallity(list.get(3));
this.address(list.get(4));
this.phoneNumber(list.get(5));
}
and the call will be like :
Person person = new Person(list);
The other answer is good, there is one trick that can make it easier to work with though. This is especially relevant if there are a large number of entries such as the 15 mentioned in the question:
public Person(List<String> list) {
int index = 0;
this.firstName(index++);
this.secondName(index++);
this.age(index++);
this.nationallity(index++);
this.address(index++);
this.phoneNumber(index++);
}
Now you can add things to the list in any position or change the order or otherwise adjust it and don't have to manually update all the indexes. It also removes the risk of human error in accidentally getting an index wrong - although you do still need to get all the fields in the right order.
Related
Say I have an array holding employee data:
[empID, empFName, empAge, empSalary, ...]
rather than each index being [0,1,...] can I instead give the index an identifier? I'm trying to create a loop where I store an array object [employee] inside of an array, with each index of the employee array holding one of the values above empID, empFName, ...,
What I'm trying to end up with is something like this:
[Employee1[101, Dave, 35, 50000], Employee2[...]...]
is this possible in Java?
Sure. Embrace what java is, which is a nominally typed system. Emphasis on nominal: Things are supposed to have names. Thus:
#Value
public class Employee {
int id;
String name;
int age;
long salary;
}
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee(101, "Dave", 35, 50000));
Some notes:
arrays are low level constructs you generally shouldn't be using unless you really know you need them, or its component type is primitive (int[] is much harder to avoid). Use Lists. These can shrink and grow and have funcioning implementations of equals and hashCode and the like.
You need to set up that class to have a constructor and such. If you're on java 14, you can use records; alternatively, you can use lombok's #Value, as in this example.
From what I'm understanding you're essentially describing a 2D array. While that's possible and could get you to where you want to go, I think it'd be a lot easier and teach you a lot more if you created an employee object and stored them in an arraylist! Then, you'd access the info you want with arraylist.get(i).someEmployeeMethod() where someEmployeeMethod() could be something like getName() or getId(). If you don't know what an object is, you will definitely need to.
I have an ArrayList of a java object with name say, "mylist".
I am getting the name of the list(mylist) from database which comes as a String. I need to find the size of this list in JAVA and need to iterate over it.
Is there a way to do this?
Edit:
To be more clear here, I have a class "Candidate"
class Candidate {
String firstName;
String lastName;
List<Education>educationRecords;
.....
}
class Education {
String school;
String degree;
.....
}
I need to populate Candidate object from a JSONObject whose structure is very different from Candidate object(so can't use Gson or jackson).
The simple fields like firstName, lastName, school and degree are stored in the database.
I fetch a Listfields and iterate over them to set the Candidate object. For setting firstName, lastName, I am using SpEL.
But, for fields like school and degree, it becomes complex as I would need to know the size of education records in JSONObject.
So, what I thought was while iterating over all fields if school field is present in Education class(using reflection), I would need to check if educationRecords is a of List type in Candidate class and then by some logic X(taking educationRecords as variable name) iterate over it.
It is the logic "X" I am missing.
I don't quite understand the use case here. However, my understanding is that you have an ArrayList<Object> mylist and you need to find the size of it based on a string retrieved from DB.
You can store the list in a cache, where the key is the name of the list and value is the actual object. You can use redis, eh-cache or memcache (Or anything similar) to achieve the same.
So when you retrieve the name from DB, get the corresponding object from the cache and do size() on the object after type casting it. If your are storing the list type instead of object type in the cache, then the last part is not needed (typecasting).
You can use a map:
Map<String, List> listMap = new Hashmap<>();
Each time you create a list - add it to your map with a key that is a name of your list. Once you get a name you can easily check if such list exists in your map, get it, check its size and iterate through it... Be careful that once you are done with your list you should remove it from your map as well as otherwise you will keep them around and it will eat your memory up.
I am currently writing code which contains an arraylist. This arraylist includes data which is name, lastname, job and id. I need to seperate the data into different arraylists. Currently i am using the method which is shown below.
for (int i = 0; i < details.size(); i = i + 4) {
names.add(details.get(i));
lastname.add(details.get(i + 1));
job.add(details.get(i + 2));
id.add(details.get(i+3));
}
I want to know if there is a better way of doing this. The initial arraylist can be very long, and i dont know if there are any issues with this method.
You asked: "I want to know if there is a better way of doing this". There is a better way.
You should consider creating a class called Record that contains the data (name, last name, job, and ID), and create an ArrayList. Then, instead of using index locations (and potentially grab the wrong data item), you could use the Record getter methods to get the data item you need (and perhaps store it in a different list).
Step 1: Create a Record class:
public class Record
{
private String firstName;
private String lastName;
private String job;
private String id;
// TODO add constructor(s), getters and setters
}
Step 2: Create a list of Records (this is an better alternative that create a list having the information in different index locations. That way, each set of name, last name, job, and ID will be self-contained which is way better than disjointed in different index locations in a list.
ArrayList<Record> records = new ArrayList<Record>();
Step 3: Instead of using index locations (and potentially grab the wrong data item), you could use the Record getter methods to get the data item you need (and perhaps store it in a different list).
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> jobs = new ArrayList<String>();
...
names.add(records.getLastName() + ", " + records.getFirstName());
jobs.add(records.getJob());
Alternatively, and maybe a better solution, you could use a Map to store this information. For example, a job ID could be the key in a Map that returns a job description and who has been assigned to perform it. Job IDs have to be unique. Adding IDs to a list can be duplicated, because the List interface doesn't restrict entering duplicate data. If you use a Map, they keys are guaranteed to be unique. The value being returned from the Map could be a Record object (or some other kind) that contains the name of the person and the job the person is responsible for. Since values can be duplicates, you can have a person performing multiple jobs, which is probably what you want to do. To use a Map:
Map<String, Record> jobs = new HashMap<String, Record>(); //This record class doesn't have ID in it.
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
jobs.put("321CBA", new Record("Bill", "Smith", "Install Light Fixtures");
A few things to consider if using a Map. If you try to make a new entry with an existing key, the old one will be overwritten.
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
jobs.put("ABC123", new Record("Bill", "Smith", "Install Light Fixtures"); //Overwrote the previous entry because key is the same
If you want to change the key for an existing value, you must obtain the value, store temporarily, remove the old record, and make a new entry with the old temp value:
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
Record rec = jobs.remove("ABC123"); // gets the record and removes old entry
jobs.put("321CBA", rec); // new job ID for old record
The main issue is that your details can have missing data. For example it has the size=5. Then your method will crush with IndexOutOfBounds. Your details list should contain a Person object which has all the details you want and then just use them to fill other lists.
The main performance kill will be the add operation since it will have to grow the data structure over time. Since you know details.size() you should initialize the other arraylists with details.size()/4.
You should also check that details.size() % 4 == 0 before the for loop. If not it means your data is somehow wrong and you will run for sure into an IndexOutOfBounds.
Just for correctness you should write i < details.size()+3 as your condition, since you will access element i+3 in the for body. You should always check for i < details.size()+x do it like this if you ever access i+x in the body. (for the largest x there will be in the body)
I want to store three values in a 2D type in java. I know that we can use List and ArrayList for storing 1D values but I need to store more than one field in a specific record. For example i have to enter the details for multiple columns i.e. (1,1),(1,2),(1,3) for details such aaaa, bbbb, cccc for a person and store them in one single row(which may consist of values which are other than string type). It should run in a loop and once details of a person is stored, it should store (2,1),(2,2),(2,3) i.e. again for a new person. How to do that?
And later on, how to retrieve and send the complete set to database together? Please help..
What you might want to do is to create a class that holds all of the information you want to keep related to a single record if it represents a concrete thing and use the List and ArrayList to store those.
What I mean by concrete thing is something that has a finite set of information that will stay the same over each object.
Something like:
public class Person
{
String name;
Integer age;
// etc...
}
This gives you two advantages over using something like a 2D array. First, it will make reading your code easier, since instead of having to remember that arrayName[x][0] is whatever you decide the first field is, you can access it using something like listItem.attributeName. The second advantage is that you can abstract out any common datahandling tasks as class methods instead of having to bloat your main class with it.
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.