How to make and populate common field in recyclerview? - java

Let say, I have a student, employee and car class in a different structure in JSON file.
I already parse them and put the respective data to its POJO classes. The things is I wanna display data to inside a recycler view.
But here I have common field both three class is name and weight.
So, I wanna pass to list of generic to recycler view and populate them by calling like this:
tvName.setText(Object(should be generic).getName());
tvWeight.setText(Object(should be generic).getWeight());
It should display name and weight all the student, employee and car .
RecyclerView looks like
---------------------------------------------------------
CarName
CarWeight
---------------------------------------------------------
EmplyoeeName
EmplyoeeWeight
---------------------------------------------------------
StudentName
StudentWeight
---------------------------------------------------------
EmplyoeeName
EmplyoeeWeight
---------------------------------------------------------
CarName
CarWeight
---------------------------------------------------------
CarName
CarWeight
---------------------------------------------------------
StudentName
StudentWeight
Any idea would be highly appreciated.

In order to achieve that, you need something called polymorphism, learn more from StackOverflow, Java Docs and Wikipedia. In order to respect that pattern I would implement the problem like this:
I would create an Interface that has the methods you need:
public interface AttributesInterface {
String getName();
double getWeight();
}
Then I would make every POJO class implement that interface, looking in the end like this:
public class Car implements AttributesInterface {
private String name;
private double weight;
#Override
public String getName() {
return null;
}
#Override
public double getWeight() {
return weight;
}
}
In the adapter you store the list like this. If a class will implement the interface, then you will be able to add it in that array. So you will have an array that will contain Student, Car, Employee in the same time.
private List<AttributesInterface> list = new ArrayList<>();
Then final step is in onBindViewHolder where you get an object from that array and set the corresponding values.
AttributesInterface object = list.get(position);
tvName.setText(object.getName());
tvWeight.setText(String.valueOf(object.getWeight()));
Also, you mentioned that you want a solution to work with multiple classes. As long as you implement the interface in each class that needs to be displayed, you can have a million classes.

You can create only one POJO class and you can add extra variable say type. So your POJO class will look like below.
public class MyClassModel {
private String type=""; // S=Student, C=Car, E=Employee
private String name="", weight="";
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
}
Now you will get type in your RecyclerviewAdapter so you can write your logic according to type of data.

Related

facing issue with unmarshalling an old xml ,after class structure got changed

I am struggling with unmarshalling an old xml file whose structure is different than my current object structure.
Previous structure
#xmlRootElement("configData")
public class configData{
private string name;
private string age;
private customObject obj;
}
My current data structure is
#xmlRootElement("configData")
public class configData{
List<SampleData> sampleDatas;;
}
public class SampleData{
private string name;
private string age;
private customObject obj;
}
How to make it work with old xml file. Please help.
Thanks
Your old structure suggest, that only one set of SampleData exists in the XML file.
So You should try something like this:
#XmlRootElement
public class ConfigData
{
// This will hide the list from JAXB
#XmlTransient
private final List<SampleData> sampleDatas = new ArrayList<>();
private SampleData getFirstSample()
{
if(sampleDatas.isEmpty())
sampleDatas.add(new SampleData());
return sampleDatas.get(0);
}
// Façade methods to delegate functionality to the list's first item...
// Only setters are required, if you just want to read in an old format.
// However this would not be optional, if you want to save to the new format...
public void setName(String name)
{
getFirstSample().setName(name);
}
public void seAge(String age)
{
getFirstSample().setAge(age);
}
public void setObj(CustomObject obj)
{
getFirstSample().setObj(obj);
}
}
public class SampleData
{
private String name;
private String age;
private CustomObject obj;
// Accessor methods...
}
The façade setter methods in ConfigData store thier values to the List's first item.
To provide the possibility to save, you should remove the #XmlTransient, and provide public getters to the fields you want to save...

Sorting an array alphabetically, but the array is full of objects, and I need to sort by a particular parameter

Let's say I have an object like:
public class Fruit{
private String name;
private int quantity;
Fruit(){}
Fruit(String name, int quantity){
this.name = name;
this.quantity= quantity;
}
public int getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And I want to sort an array full of Fruit objects alphabetically by name. My initial thought, Arrays.sort(a.getName()); wouldn't work, because .getName() only works on individual objects. One idea I had was put all the names into an array, sort those alphabetically, then run a loop to sort the objects using this list, but that seems absurdly cumbersome.
Any ideas? As you can tell, I'm very new to working with objects in this manner.
Either you make your Fruit class Comparable by implementing the compareTo method, or you provide a custom Comparator to the Arrays.sort method:
Arrays.sort(fruits, Comparator.comparing(Fruit::getName));
This uses the Comparator.comparing method.
I recommend you redefine your Fruit class to implement Comparable<Fruit> so that you can easily sort a Fruit[] by each elements' respective name field:
public class Fruit implements Comparable<Fruit> {
// Code here...
#Override
public int compareTo(Fruit fruit) {
return name.compareTo(fruit.name);
}
}
Now, you can call Arrays#sort on Fruit[] and it will sort them lexicographically by name.
You don't need to make your Fruit class implement Comparable<Fruit>; you can do it by passing a custom Comparator to the array, like this:
Array<Fruit> sortedArray = sort(fruitArray, new Comparator<Fruit>() {
public int compare(Fruit left, Fruit right) {
return left.name.compareTo(right.name);
}
public int equals(Object obj) { return 0; /* you can ignore this */ }
});

How to store data in a class with multiple variations

So I'm kinda curious how can I store for example a list of items in my class with prices, code, quantity and so on.
Is there an easy way to have it all related and not creating a function for each variable?
You can define a List object in your class.
For example a person that has credit cards:
public Class Person {
private String name;
private List<CreditCard> creditCards;
// toString, equals, constructor, etc.
public void setCreditCards(List<CreditCard> creditCards) {
this.creditCards = creditCards;
}
public List<Creditcard> getCreditCards() {
return this.creditCards;
}
// more getters and setters
And the Credit Card:
public Class CreditCard {
private String number;
private Date expiryDate;
// getters and setters
}
And then you can make calls like this:
Person person = new Person();
List<CreditCard> cards = person.getCreditCards();
for(CreditCard card: cards) {
String number = card.getNumber();
}
A Java class can be thought of as a collection of fields (variables), and methods (functions).
The way you make a class hold more than one piece of data is to add more fields, and more methods to access those fields.
For example:
public class Cat {
int id;
String name;
double price;
public Integer getId() {
return this.id;
}
//........etc
}
You can then store that in your list and access different bits of data.

How do I use Java getters and setters with a collection of data without explicitly typing out the attributes for each item?

I am very new to Java and to programming in general, and I have an assessment to complete where I load employees (with name, age, and department attributes; department can be only one of four enumerated values) into a program that will sort them by age and tell if the age is a prime number. The assignment requires Company, Department, and Employee classes. I am confident that I can figure out age/prime components — I know how to google for algorithms. What I am struggling with is putting all the discrete pieces into a cohesive whole.
Here is what I have so far. I've put in one employee, but the way I'm doing it seems completely inelegant and inefficient. I am sure there is a better way, but I've hit a mental block.
EDIT: as was pointed out below, I was unclear. What I am asking help with is populating the data structure.
Company class:
public class Company {
static Employee one = new Employee();
public static void main(String[] args) {
one.setName("Counting Guru");
one.setAge(55);
one.setDepartment(DepartmentList.ACCOUNTING);
}
}
DepartmentList class:
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
public enum DepartmentList {
ACCOUNTING, MARKETING, HUMANRESOURCES, INFORMATIONSYSTEMS;
public static void main(String[] args) {
Map<DepartmentList,String>
enumMap=new EnumMap<DepartmentList,String>(DepartmentList.class);
enumMap.put(DepartmentList.ACCOUNTING, "Accounting");
enumMap.put(DepartmentList.MARKETING, "Marketing");
enumMap.put(DepartmentList.HUMANRESOURCES, "Human Resources");
enumMap.put(DepartmentList.INFORMATIONSYSTEMS, "Information Systems");
Set<DepartmentList> keySet = enumMap.keySet();
for (DepartmentList department : keySet) {
String value = enumMap.get(department);
System.out.println("ENUMMAP VALUE:"+value);
}
}
}
Employee class:
public class Employee {
String empName;
int empAge;
DepartmentList empDept;
Employee() {
}
public String getName() {
return empName;
}
public void setName(String name) {
this.empName = name;
}
public int getAge() {
return empAge;
}
public void setAge(int age) {
this.empAge = age;
}
public DepartmentList getDepartment() {
return empDept;
}
public void setDepartment(DepartmentList department) {
this.empDept = department;
}
public Employee(String empName, int empAge, DepartmentList empDept){
}
}
I also have a Department class, but it's currently empty.
Am I on the right track? Can someone give me a nudge? Thank you!
Don't hard-code the data inside the Java program. Put the data in a file and write methods to load the data.
If you MUST hardcode the data in the program, use something like this sample:
public class Employee
{
String name;
int age;
public Employee(String name, int age)
{
this.name = name;
this.age = age;
}
// getters, setters, etc.
}
In the main program
private static Employee[] empData =
{
new Employee("John Smith", 50),
new Employee("Fred Jones", 25),
.
.
.
};
Now you have a static array of Employee objects that you can "load" into your data structure.
If you're asking if there is something like a property in Java, no, there isn't (at least not yet).
If you're asking how to populate your objects something like an IOC container, like Spring, would be a better choice.
Now as it comes to your code you have two main methods in two different classes. Only one will be called. If you want to create a static instance you will be better do
static Employee one = new Employee("Counting Guru", 55, DepartmentList.ACCOUNTING);
or
static Employee one = new Employee();
static {
one.setName("Counting Guru");
one.setAge(55);
one.setDepartment(DepartmentList.ACCOUNTING);
}
When it comes to the enum then you'll better define a constructor for it
public enum DepartmentList {
ACCOUNTING("Accounting"), MARKETING("Marketing");
private String displayName;
public DepartmentList(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return diplayName;
}
}
In the Employee constructor you need to assign the field values to the ones received as arguments.

Java: Adding fields and methods to existing Class?

Is there, in Java, a way to add some fields and methods to an existing class?
What I want is that I have a class imported to my code, and I need to add some fields, derived from the existing fields, and their returning methods.
Is there any way to do this?
You can create a class that extends the one you wish to add functionality to:
public class sub extends Original{
...
}
To access any of the private variables in the superclass, if there aren't getter methods, you can change them from "private" to "protected" and be able to reference them normally.
Hope that helps!
You can extend classes in Java. For Example:
public class A {
private String name;
public A(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class B extends A {
private String title;
public B(String name, String title){
super(name); //calls the constructor in the parent class to initialize the name
this.title= title;
}
public String getTitle(){
return this.title;
}
public void setTitle(String title) {
this.title= title;
}
}
Now instances of B can access the public fields in A:
B b = new B("Test");
String name = b.getName();
String title = b.getTitle();
For more detailed tutorial take a look at Inheritance (The Java Tutorials > Learning the Java Language > Interfaces and Inheritance).
Edit: If class A has a constructor like:
public A (String name, String name2){
this.name = name;
this.name2 = name2;
}
then in class B you have:
public B(String name, String name2, String title){
super(name, name2); //calls the constructor in the A
this.title= title;
}
The examples only really apply if the class you're extending isn't final. For example, you cannot extend java.lang.String using this method. There are however other ways, such as using byte code injection using CGLIB, ASM or AOP.
Assuming this question is asking about the equivalent of C# extension methods or JavaScript prototypes then technically it is possible as this one thing that Groovy does a lot. Groovy compiles Java and can extend any Java class, even final ones. Groovy has metaClass to add properties and methods (prototypes) such as:
// Define new extension method
String.metaClass.goForIt = { return "hello ${delegate}" }
// Call it on a String
"Paul".goForIt() // returns "hello Paul"
// Create new property
String.metaClass.num = 123
// Use it - clever even on constants
"Paul".num // returns 123
"Paul".num = 999 // sets to 999
"fred".num // returns 123
I could explain how to do the same way as Groovy does, but maybe that would be too much for the poster. If they like, I can research and explain.

Categories