Creating a list out of my DTO - java

I have a year object. For now lets say only two years and its getters and setters
private String mYearOne;
private String mYearTwo;
public String getmYearOne() {
return mYearOne; }
public void setmYearOne(String mYearOne) {
this.mYearOne = mYearOne; }
public String getmYearTwo() {
return mYearTwo; }
public void setmYearTwo(String mYearTwo) {
this.mYearTwo = mYearTwo; }
Then each year has three insurance plans. And its getters and setters.
private String healthPlan;
private String carPlan;
private String housePlan;
private String healthPlanTwo;
private String carPlanTwo;
private String housePlanTwo;
public String getHealthPlan() {
return healthPlan; }
public void setHealthPlan(String healthPlan) {
this.healthPlan = healthPlan; }
public String getCarPlan() {
return carPlan; }
public void setCarPlan(String carPlan) {
this.carPlan = carPlan; }
public String getHousePlan() {
return housePlan; }
public void setHousePlan(String housePlan) {
this.housePlan = housePlan; }
public String getHealthPlan() { //For the second year
return healthPlan; }
public void setHealthPlan(String healthPlan) {
this.healthPlan = healthPlan; }
public String getCarPlan() {
return carPlan; }
public void setCarPlan(String carPlan) {
this.carPlan = carPlan; }
public String getHousePlan() {
return housePlan; }
public void setHousePlan(String housePlan) {
this.housePlan = housePlan; }
public String getHealthPlanTwo() {
return healthPlanTwo; }
public void setHealthPlanTwo(String healthPlanTwo) {
this.healthPlanTwo = healthPlanTwo; }
public String getCarPlanTwo() {
return carPlanTwo; }
public void setCarPlanTwo(String carPlanTwo) {
this.carPlanTwo = carPlanTwo; }
public String getHousePlanTwo() {
return housePlanTwo; }
public void setHousePlanTwo(String housePlanTwo) {
this.housePlanTwo = housePlanTwo; }
You will notice the code is bulky. I need to define them in a <list> of year. So that if 10 years are considered, I would have 10 multiplied
by 3 = 30 plans and its getters and setters respectively.
How could this be done?

I think your best bet will be to maintain a count of number of years and arraylists for the insurance plans. This way, you can get the arraylist once and get the insurance plan details for whatever year you actually want. This will be characterized by a single insurance plan arraylist and a single arraylist for years.
private ArrayList mYear;
private ArrayList healthPlan;
private ArrayList carPlan;
private ArrayList housePlan;
public String getHousePlanForYear(String year){
return housePlan.get(mYear.indexOf(year));
}
public void setHousePlanForYear(String housePlan, String year){
this.housePlan.set(mYear.indexOf(year), housePlan);
}
Similarly for the other plans. Of course, all this is assuming that the year is always present and other boundary conditions. Just add your boundary checks in these getters and setters and you will be good to go. :)

I see a design/domain modelling problem here. A person can ideally have multiple "plans" and "riders" attached to each plan. This should clearly be abstracted away properly by creating a "PlanCollection" class or simply maintaining a list of "plans" which all extend/implement a common "Plan" class/interface.
Each plan can have a "plan" duration and a start date. Also, logically, you don't attach plans to "year" but the timeline information is encapsulated in the Plan itself (like start and duration as mentioned above).

Take a look at enums and maps. The enum would specify car, house etc.
You could create a map that takes an enum as key and a List of years as the key. Don't be tempted to create YearThree etc.
On a note of style: if you intend to use m to prefix fields, take the m out of the setter. E.g. setYearOne not setmYearOne.
Choose your types wisely, don't use a String if an int is better.

Related

how to change name based on activity in model using android

I create a model called Review. There are two activities (QualityReivewActivity.java & FairnessReivewActivity.java) will call the model whenever user leaves a comment.
I want to
public class Review {
float fairness_rating; //change the name to quality_rating
String post_id;
String review_time;
String reviewer_id;
String text_review;
public Review(){
//
}
Review(float fairness_rating, String post_id, String review_time, String reviewer_id, String text_review){
this.fairness_rating=fairness_rating;
this.post_id=post_id;
this.review_time=review_time;
this.reviewer_id=reviewer_id;
this.text_review=text_review;
}
public float getFairness_rating() {
return fairness_rating;
} //change to getQuality_rating if actitivty is QualityReivewActivity.java
public String getPost_id() {
return post_id;
}
public String getReview_time() {
return review_time;
}
public String getReviewer_id() {
return reviewer_id;
}
public String getText_review() {
return text_review;
}
}
and this is the segment of code of QualityReivewActivity
Review c = new Review(mRatingBar.getRating(), post_id, timedComment.toString(), reviewer_uid, my_comment.getText().toString()); //
However, the QualityReviewActivity always shows "fairness_rating". How can I make a dynamic model name to change to "quality_rating" if I am calling from QualityReviewActivity?
You can solve it by using enum.
public enum ratingType {
 Quality,
 Fairness
}
Then use that enum in your function.
public float get_rating(ratingType type) {
 switch (type) {
 case Quality:
  return quality_rating;
 case Fairness:
  return fairness_rating;
 }
}
After that, depending on the class, you can pass the necessary arguments and it will work.
I'm not good at Java, so it may not work if I write it as it is, but the idea is ok.

Java - how to call a method of corresponding class based on string using enum/factory pattern

Yes, I read many examples in web, but I didn't find a way how to call a method based on string value. May be I am not searching in right way... I wrote all code, but don't know how to call the method.
fyi: I don't want to use if else or switch case
Here is what I want:
I get the card reader type as String from database. I have to call the corresponding class' method.
My code:
LoginPanel.java
public class LoginPanel {
public static void main(String args[]) {
String readerType = "Omnikey5427-CK"; // I get this ("Omnikey5427-CK" or "Omnikey5427-G2") from a database as String
// I WANT TO CALL getCardNumber() method of respective class
}
}
ISmartCardReader.java
public interface ISmartCardReader {
public Integer getCardNumber();
}
Omnikey5427G2.java
public class Omnikey5427G2 implements ISmartCardReader {
public Omnikey5427G2() {
System.out.println("G222222222222222...");
}
public Integer getCardNumber() {
return 222;
}
}
Omnikey5427CK.java
public class Omnikey5427CK implements ISmartCardReader {
public Omnikey5427CK() {
System.out.println("CKKKKKKKKKKKKKKK...");
}
public Integer getCardNumber() {
return 111;
}
}
SmacrtCardEnumFactory.java
public enum SmacrtCardEnumFactory {
OMNIKEY5427CK("Omnikey5427-CK") {
public ISmartCardReader geInstance() {
return new Omnikey5427CK();
}
},
OMNIKEY5427G2("Omnikey5427-G2") {
public ISmartCardReader geInstance() {
return new Omnikey5427G2();
}
};
private String cardReaderName;
private SmacrtCardEnumFactory(String cardReaderName) {
this.cardReaderName = cardReaderName;
}
public String cardReaderName() {
return cardReaderName;
}
}
You can use valueOf() function of enum provided your enum sonstant names match strings used to lookup (you may use cardName.toUpper()). You may also create objects for all the card types and store them in a hash map and then lookup them. You can also write some fatory method, but this will be if-then-else or switch inside
You could iterate over the factory's values() and get the one that matches the string:
public enum SmacrtCardEnumFactory {
// current code omitted for brevity
public static getSmartCardReader(String name) {
return Arrays.stream(values())
.filter(r -> r.cardReaderName().equals(name))
.map(SmacrtCardEnumFactory::getInstance();
.orElse(null);
}
}

Constructors and methods in java

I want to create the below class
associatename:String
workstatus:String
associate() :constructor
getassociatename():String
setassociatename(String):void
getworkstatus()String
tracksassociatestatus():int
setworkstatus(String):void
The trackAssociateStatus method takes the number of days as argument and sets the work status of the associate based on the number of days. The first 20 days they learn “C”, the next 20 days they learn “Java” In the Main class invoke the trackAssociateStatus method and find the work status and display the output.
output:The associate abc work status:Project phase
I tried this....But i got error
//associate class
public class associate{
private int associatename;
private String workstatus;
private int days;
void associate()
{
getassociatename();
setassociatename();
getworkstatus();
tracksassociatestatus();
setworkstatus();
}
public int getassociatename()
{
return associatename;
}
public void setassociatename(int associatename)
{
this.associatename=associatename;
}
public String getworkstatus()
{
return workstatus;
}
public void tracksassociatestatus(int days)
{
if(days<20)
setworkstatus("C");
else
setworkstatus("Java");
}
public void setworkstatus(String workstatus)
{
this.workstatus=workstatus;
}
}
//main class
associate a =new associate();
Scanner in=new Scanner(System.in);
int associateid=0;
String workstatus=null;
int days=0;
System.out.println("Enter the associateid:");
associateid=in.nextInt();
a.associateid=(associateid);
System.out.println("Enter the no of days:");
days=in.nextInt();
a.trackassociatestatus();
System.out.println("The id is "+a.getassocaiteid()+" work status "+a.getworkstatus());
Based on your (seemingly) UML spec, your class would look like the following:
public class Associate {
private String associateName;
private String workStatus;
public Associate() {
// This constructor is optional, a no-args constructor is added by the compiler to any class not explicitly naming a constructor.
}
public String getAssociateName() {
return associateName;
}
public void setAssociateName(String associateName) {
this.associateName = associateName;
}
public String getWorkStatus() {
return workStatus;
}
public void setWorkStatus(String workStatus) {
this.workStatus = workStatus;
}
public int tracksAssociateStatus() {
// TODO write logic here
return 1; // TODO change to whatever you need to return
}
}
You were specifying int for getAssociateName, when associateName is a String. This won't work; you need your getter return type to be the same as your field data type, or you need to convert the data to the method's return type. (The former is best practice).
Constructors don't specify a type, the class name is used and the compiler will understand what you want to do (which is return a new instance of the class). Therefore, your void associate() will tell the compiler "create a method called associate that doesn't return anything".
Well, would be nice if you provide the error itself for us.
But meanwhile, have you notice that your tracksassociatestatus method recieves an integer parameter days, and your constructor passes nothing to it?
So try changing your constructor to be something like:
Public associate() {
getassociatename();
setassociatename();
getworkstatus();
tracksassociatestatus(10);
setworkstatus();
}
For a cleaner code, check the other answer.
If you still have errors, please share them.
import java.util.*;
public class Associate
{
private String associateName;
private int workStatus;
private int days;
Scanner sc = new Scanner(System.in);
public String getAssociateName()
{
System.out.println("Enter the Associate id:");
associateName = sc.nextLine();
return associateName;
}
public void setassociatename(int associatename)
{
this.associateName=associateName;
}
public String tracksAssociatename()
{
return associateName;
}
public int getWorkStatus()
{
System.out.println("Enter the number of days");
days = sc.nextInt();
return days;
}
public void setWorkStatus(String workStatus)
{
this.workStatus=workStatus;
}
enter code here
public `enter code here`int tracksAssociateStatus()
{
return days;
}
public static void main(String args[])
{
Associate obj = new Associate();
obj.getAssociateName();
obj.getworkstatus();
System.out.println("The Associate name "+obj.tracksAssociatename()+" work Status "+obj.tracksAssociateStatus());
}
}

Define static data in separate place to reuse

I have list of string data that are not change during any operation inside my program. But i need to access those data in several places by using key.
As a example: (1,ANN)(2,ALEX)(3,ANDROW)
Is there any way to store these data in separate class.Can I use java enum for this. thank you
With the use of enum you can implement something like below:
public enum Name {
ONE {
#Override
public String getName() {
return "ANN";
}
},
TWO {
#Override
public String getName() {
return "ALEX";
}
},
THREE {
#Override
public String getName() {
return "ANDROW";
}
};
public abstract String getName();
}
Then you can get the the names :
System.out.println(Name.ONE.getName());
This is really a good candidate for using Map. Where you can use your numbers as keys and String's as values.
https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html
Map<Integer, String> map = new HashMap<Integer,String>();
Map<Integer,String> is one option and if key is also constant you could define string variable like
public static final string ONE = "ANN";
public static final string TWO = "ALEX";
A different way to use enums to define a statically mapping:
public enum Names {
ONE("ANN"),
TWO("ALEX"),
THREE("ANDREW");
private final String name;
private Names(String name){
this.name=name;
}
public String getName() {
return this.name;
}
}
This is only applicable to real-static values (change to values does mean a code change), but you can easily define multiple properties as well.
You can do the following:
import java.util.HashMap;
public class Main {
static HashMap<Integer,String>data = new HashMap<>();
public static void main(String[] args) {
// write your code here
data.put(data.size(),"ALEX"); // if you want 1-based indexing,
data.put(data.size(),"ANDROW"); // then use data.size()+1
data.put(data.size(),"ANN"); // instead of data.size()
for (int i = 0; i<data.size(); i++){
System.out.println(i+" : "+data.get(i)); // use i+1 if 1-based indexing
}
}
}

Parsing csv via column order in spring batch

I've got a CSV in the format...
Kitten URL,Kitten Name,# of Reviews,Rating,Categories,,,,,,,,,,,,,
www.happykitten.com,happykittem.com,111746,7.8,Clothes & Fashion,Fashion Accessories,Ladies wear,Menswear,,,,,,,,,,
animedkitten.co.uk,Animed Kitten,33918,9.6,Pets,,,,,,,,,,,,,
So the first columns are Kitten URL,Kitten Name,# of Reviews,Rating then the rest are the possible categories listed as extra properties.
I'm trying to use Spring batch so I'm specifying the dumb object to represent this CSV. The first problem I've got is (using the example from Spring documentation I don't see how I can parse a CSV with spaces in the title. Is it possible to use Spring batch like this? Can I annotate each getting like in Hibernate with the title of the csv column?
My dumb object was going to be something like...
public class ImportDataObject {
private String kittenUrl;
private String kittenName;
private int numOfReviews;
public String getKittenUrl() {
return kittenUrl;
}
public void setKittenUrl(String kittenUrl) {
this.kittenUrl = kittenUrl;
}
public String getKittenName() {
return kittenName;
}
public void setKittenName(String kittenName) {
this.kittenName = kittenName;
}
public int getNumOfReviews() {
return numOfReviews;
}
public void setNumOfReviews(int numOfReviews) {
this.numOfReviews = numOfReviews;
}
}
I only really want to read the first 2 columns, append some strings, then persist the rest of the CSV.
I'm also considering the best approach to use for these multiple commas afterwards. Unfortunately this is how I've got the data and it's not something I can change.
You can implement FieldSetMapper for your object and then set it to your DefaultLineMapper. Your implementation of FieldSetMapper can work on positions and you can parse only first few positions and set it to your bean.
Here is suggestion based on code from URL you posted:
reader.setLineMapper(new DefaultLineMapper<ImportDataObject>());
setFieldSetMapper(new ImportDataObjectFieldSetMapper());
}});
setLinesToSkip(1); //skip header since read int will throw exception and I assume you do not need header info
}});
Then changes to POJO object to save list of categories:
public class ImportDataObject {
private String kittenUrl;
private String kittenName;
private int numOfReviews;
private int rating; //add getters and setters
private List<String> categories; //add getters and setters
public String getKittenUrl() {
return kittenUrl;
}
public void setKittenUrl(String kittenUrl) {
this.kittenUrl = kittenUrl;
}
public String getKittenName() {
return kittenName;
}
public void setKittenName(String kittenName) {
this.kittenName = kittenName;
}
public int getNumOfReviews() {
return numOfReviews;
}
public void setNumOfReviews(int numOfReviews) {
this.numOfReviews = numOfReviews;
}
}
And here is FieldSetMapper:
public class ImportDataObjectFieldSetMapper implements FieldSetMapper<ImportDataObject> {
#Override
public ImportDataObject mapFieldSet(final FieldSet fieldSet) throws BindException {
final ImportDataObject importDataObject = new ImportDataObject();
importDataObject.setKittenUrl(fieldSet.readString(0));
importDataObject.setKittenName(fieldSet.readString(1));
importDataObject.setNumOfReviews(fieldSet.readInt(2));
importDataObject.setRating(fieldSet.readInt(3));
importDataObject.setCategories(new ArrayList<String>());
for (int i = 4; i < fieldSet.getFieldCount(); i++) {
importDataObject.getCategories().add(fieldSet.readString(i));
}
return importDataObject;
}
}

Categories