Specific Datatype for this situation? - java

I want to pull data from a database. Name, Age, Sex, Location.(maybe more fields)
I want to hold the data in an object similar to how I would expect it to look in a JSON object.
Like:
myData{
row1[name:beavis, age:48, sex:male, location:Joburg]
row2[name:quintus, age:43, sex:, location:Helsinki]
...up to say 500 rows
}
So i'd like to be able to do tempName = row(i).name and so on in java.
Any suggestions.

// Defines a Person datatype
public class Person {
// fields
private String name;
private int age;
private String location;
// gets the value of a field
public String getName() {
return name;
}
// sets the value of a field
public void setName(aName) {
this.name = aName;
}
}
What I did here was define a Person type with a number of fields. Also I give here an example of a setter and getter for the name field. You can put them in an array or collection. For example:
Person people[] = new Person[2];
people[0] = new Person();
people[0].setName("Alice");
You can also dispense with the setters and getters by making the fields public, but I wouldn't recommend it.

A straight translation of that data structure would be along the lines of
List<Map<String, Object>> myData
so you'd be able to call
tempName = (String) myData.get(i).get("name");
Like the JSON array, this doesn't enforce typing (which you'll have to deal with explicitly in Java) and doesn't limit the fields to only those from the database.
If all the database values are strings, things get cleaner as no casts are necessary.
List<Map<String, String>> myData
tempName = myData.get(i).get("name");

Related

Return different value types from an object, depending on the type cast

I've seen methods that return a different value types from an object depending on the type cast, similar to this:
(String) Object.get() //returns a string
(Integer) Object.get() //returns an int
etc.
I’m trying to replicate this behavior (for learning purposes) by creating an Employee class like this:
public class Employee {
String name;
int age;
public Employee (String name, int age){
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName(){
return name;
}
}
Now, let's assume I create a new Employee object:
Employee tomJones = new Employee("Tom Jones", 38);
Is it possible to somehow do this (see below)?
(String) tomJones.get() //returns “Tom Jones”
(Integer) tomjones.get() //returns 38
I'm trying to replicate some behavior that I've previously seen in code and not having all the problem's details makes it quite hard for me as a beginner to come up with something. So, I tried using different interfaces and some lambdas, but only managed to make a mess, with no result.
That is not possible and if you are trying to overload the method then the number of parameters in two methods should be different or the data types of the parameters or the Order of the parameters.

How to create list of Maps from List of Object in java without having getKey method?

How to create a list of maps, where each key name is inferred from name of the class attribute, and value is to be put by getter method
I am having following class in java
class DTA {
private String id;
private String age;
#Override
public String toString() {
return "DTA{" +
"id='" + id + '\'' +
", age='" + age + '\'' +
'}';
}
public DTA(String id, String age) {
this.id = id;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
I am having a list of objects of type DTA
List<DTA> listA = new ArrayList<>();
listA.add(new DTA("A", "15"));
listA.add(new DTA("B", "25"));
I want to create an ordered list of maps (somewhat like scala) which has following content.
List<? extends Map<String, String>>
List(Map("id"->"A", "age"->"15"), Map("id"->"B", "age"->"25"))
Without "dynamics", the straight forward thing might look like:
List<Map<String, String>> x = listA
.stream()
.map(this::toMap)
.collect(Collectors.toList());
with a local helper, such as:
private Map<String, String> toMap(DTA dta) {
Map<String, String> rv = new HashMap<>();
rv.put("id", dta.getId());
rv.put("age", dta.getAge());
return rv;
}
In order to be fully dynamic here, you would have to use reflection to query the field names. You can find examples how to do that here.
But I strongly suggest to not do that: reflection should always be your last resort. The notion of DTA suggests that you have that object data coming from some "service" anyway. If so, why first serialize into a specific DTA class, to then "flatten" that information into some generic Map structure?!
Meaning: when that service gives you objects that are serialized as, say JSON, or XML ... then it would be much better to simply use a library like gson or jackson to directly deserialize that data into such generic "flat" Map-based objects. Jackson for example has a JsonNode class. When you deserialize into such objects, you get that mapping of field names for free! See here more example code.
The point is: identifying fields using reflection is possible. But reflection code is always tedious, and error prone. If possible, stay away from doing that yourself.
Basically, the tool used to "look into" the contents of classes in Java is called reflection. For example, if your object is a POJO (Plain Old Java Object), you can iterate over all fields in the class in the following way:
DTA obj; // some object, I assume it's initialized
Field[] fields = DTA.class.getDeclaredFields();
Map<String, Object> valuesMap = new HashMap<>();
for (field : fields) {
boolean wasAccessible = field.isAccessible(); // check if class has access control disabled
field.setAccessible(true); // disable access control (private/protected) to extract value
valuesMap.put(field.getName(), field.get(obj));
field.setAccessible(wasAccessible); // return flag to initial value
}
However, accessing values via reflection this way is notoriously hacky. Unless you have good reasons to do it yourself, try using a framework that automates tasks like that rather than writing code like this from scratch.
Also, reflection is slow. Accessing Field entities like that for every single object is suboptimal, if you ever want to really write code like this, you should cache the Field objects in a Map<String, Field> and only do the setAccessible override and the Field retrieval once for every collection of DTA objects.

Using Amazon's Java Alexa Skill Kit, can I put a custom Java object into a session attribute?

I'm using the Alexa Skill Kit for Java to build a custom Skill. I am trying to use a custom session attribute, co.prosody.util.PaInputData, in com.amazon.speech.speechlet.Session.
No trouble with session.setAttribute("inputData", paInputData), but when I retrieve the attribute (PaInputData)session.getAttribute("inputData"), I get a class cast exception:
"errorMessage": "java.util.LinkedHashMap cannot be cast to co.prosody.util.PaInputData"
Is it possible to get my object back?
Attribute objects that belong to the session that are not Strings will be turned into Linked Hash Maps, mapping the name of each instance variable to that of its value. For Objects that are not too complex, you can simply fetch these values by accessing each key of the Linked Hash Map that is associated with this object that belongs to your session's attributes, and reconstruct the object that way. (Note that you will need getters associated with your instance variables) You will not, however, be able to directly cast whatever object was stored in the attributes of your session to the object you desire/expect.
So let's say, for example, I have an Dog object, with two fields:
public class Dog{
private String name = "Spot";
private int age = 20;
public Dog(){
}
public Dog(String nIn, int aIn){
name = nIn;
age = aIn;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
}
If this was stored in my session's attributes with a key of "MY_DOG", I could reconstruct the object this way:
LinkedHashMap<String, Object> myDog = (LinkedHashMap<String, Object>)session.getAttribute("MY_DOG");
String fetchedName = (String)myDog.get("name"); //this will return "Spot"
int fetchedAge = (Integer)myDog.get("age"); //this will return 20
Dog copyDog = new Dog(fetchedName, age);//effectively copies the Dog object

Java QueryDSL 3.6.0 Projection.bean(Person.class, person.firstName, person.count())

I am using QueryDSL in my project to return a list of Person groupBy LastName and no of persons with that lastName. Below is the Person.java
#Entity
class Person {
private String firstName;
private String lastName;
private boolean isCitizen;
private int age;
private int groupByCount; //Property to return groupByCount - could use Group tuple for this, but doing a research trying to set it as an object field.
//Constructors to support n! ways of object creation - where n is no of fields in the object
public Person(String lastName, int groupByCount){
this.lastName = lastName;
this.groupByCount = groupByCount;
}
public Person(int age, int groupByCount){
this.age = age;
this.groupByCount = groupByCount;
}
public Person(boolean isCitizen, int groupByCount){
this.isCitizen = isCitizen;
this.groupByCount = groupByCount;
}
// keeps going to cover all possible constructors - i want to avoid this for maintainability reasons - want to be able to build objects dynamically with different parameters
//Below is code for Getter and setters for above fields
}
The QueryDSL query which uses these Constructors are below.
personRepo.getQueryDSL().createQuery(person).groupBy(person.lastName)
.list(Projections.constructor(Alarm.class, person.lastName, person.count());
personRepo.getQueryDSL().createQuery(person).groupBy(person.age)
.list(Projections.constructor(Alarm.class, person.age, person.count());
personRepo.getQueryDSL().createQuery(person).groupBy(person.isCitizen)
.list(Projections.constructor(Alarm.class, person.isCitizen, person.count());
How to avoid writing those n! constructors for a class with n fields using QueryDSL ?? I tried Projections.bean like below, after removing the constructors in the Person class
personRepo.getQueryDSL().createQuery(person).groupBy(person.isCitizen)
.list(Projections.bean(Alarm.class, person.isCitizen, person.count());
It complains .count() is not a valid expression. It is notable to assign the value of count to groupByCount field in person object. How to set groupByCount of the person object with person.count() value using Projections.bean method ??
Thanks in Advance. Really appreciate your help.
I believe that Projections.fields is what you're looking for. Have the setter names in the POJO mirror the column names in the query - it looks like you already have this in place.
I chained .as method on top of .count to groupByCount attribute as shown below. This way I was able to avoid writing n! constructors.
personRepo.getQueryDSL().createQuery(person).groupBy(person.isCitizen)
.list(Projections.bean(Alarm.class, person.isCitizen,
person.count().as(person.groupByCount));

Link ArrayLists and save data on file

I am working on a Java app for a school project where we have to enter user information: Name, Student ID and their points. How can I store all the data for each user on an ArrayList (or an Array or really whatever type) so I can keep track of all the data.
Example:
John Doe - 401712 - 20 points
Jack Young - 664611 - 30 points
The I want to be able to call methods like setPoints to change the point values for whatever the student selected is.
Here's the problem: How can I link the ArrayList together. If I have three ArrayLists, how does Java know what name, student id and points are associated together?
All the ArrayLists are stored in a class called Data.
Data data = new Data();
Also, all the ArrayLists in the Data class should be outputted to a file which will be loaded next time the app is opened.
I will try to answer any questions.
You need to define a class which contain 3 data fields as follows
Name
Student ID
their points
But not to forget, the class has to have other necessary elements of a class like:
Constructor
Overloaded Constructors if they are necessary
Accessors
Mutators
Note: For accessing each part of an object in your arrayList, you can use accessors. For manipulating each part of an object in your arrayList, you can use mustators.
After having such a class, you can define a arrayList that contain elements with type of class you have already define
Like:
List<Your Type of class > students = new ArrayList<Your Type of class>;
After Java 7, you can do
List<Your Type of class > students = new ArrayList<>;
which is diamond inference.
If you are looking for a specific id number in your arrayList, you can do something like:
public boolean findIdNumber(int idNumber){
for(int i=0; i< students.size; i++)
if(students.get(i).getID() == idNumber)
return true;
else
return false;
}
Warning:
what I have done are suggestions for you to be able to look for what you want smoother. You need to do necessary changes in order to comply what you were
asked to do
You need to create a class named Student, and then declare an array/ArrayList of the Student type. Your Student class must have a constructor that sets the fields of an instance of the Student class (the created instance is now called an object).
So first create a Student class in the same package in which your other class is (the class in which your main method is):
public class Student {
private String firstName;
private String lastName;
private String studentId;
private int points;
public Student(String firstName, String lastName, String studentId, int points) {
this.firstName = firstName;
this.lastName = lastName;
this.studentId = studentId;
this.points = points;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}
Then in your main method or wherever you like, create a Hashmap to hold your Student objects. A map/hashmap is a collection just like an ArrayList to hold a set of objects. In your use case, it is better to use a hashmap because finding/retrieving a specific student object is much faster and easier when you use a hashmap.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// a map is a "key-value" store which helps you search items quickly
// (by only one lookup)
// here you consider a unique value of each object as its 'key' in the map,
// and you store the whole object as the value for that key.
// that is why we defined Student as the second type in the following
// HashMap, it is the type of the "value" we are going to store
// in each entry of this map.
Map<String, Student> students = new HashMap<String, Student>();
Student john = new Student("John", "Doe", "401712", 20);
Student jack = new Student("Jack", "Young", "664611", 30);
students.put("401712", john);
students.put("664611", jack);
Student johnRetrieved = students.get("401712");
// each hashmap has a get() method that retrieves the object with this
// specific "key".
// The following line retrieves the student object with the key "664611".
Student jackRetrieved = students.get("664611");
// set/overwrite the points "field" of this specific student "object" to 40
johnRetrieved.setPoints(40);
int johnsPoints = johnRetrieved.getPoints();
// the value of johnsPoints "local variable" should now be 40
}
}
The classical object-oriented approach would be to create a Student class including name, ID and points and storing list of Student objects in a single ArrayList.
class Student{
private String id;
private String name;
private int points;
public Student(String id, String, name, int points){
this.id = id;
this.name = name;
this.points = points;
}
}
..
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student(1, 'John Doe', 1000));
String id = students.get(0).id;

Categories

Resources