I have 3 classes: Main, AutoHuur, Auto. Everythign works but 1 thing. I can't seem to get the "Prijs" variable from my Auto.class to display in my toString in my AutoHuur.class. It keeps showing up as 0. Why is this? (I know I initialize it to 0 if it's a null, but why is it a null and not the value from the Auto.class variable prijsPerDag?) Thank you
Main.class:
public class Main{
public static void main(String[] args) {
AutoHuur ah1 = new AutoHuur();
System.out.println("Eerste autohuur:\n" + ah1 + "\n");
Klant k = new Klant("Mijnheer de Vries");
k.setKorting(10.0);
ah1.setHuurder(k);
Auto a1 = new Auto("Peugeot 207", 50.0);
ah1.setGehuurdeAuto(a1);
ah1.setAantalDagen(4);
System.out.println("Eerste autohuur:\n" + ah1 + "\n");
AutoHuur ah2 = new AutoHuur();
Auto a2 = new Auto("Ferrari", 3500.0);
ah2.setGehuurdeAuto(a2);
ah2.setHuurder(k);
ah2.setAantalDagen(1);
System.out.println("Tweede autohuur:\n" + ah2 + "\n");
System.out.println("Gehuurd: " + ah1.getGehuurdeAuto());
System.out.println("Gehuurd: " + ah2.getGehuurdeAuto());
}
}
Autohuur.class:
public class AutoHuur {
private Klant huurder;
private Auto gehuurdeAuto;
private Auto prijs;
private Integer aantalDagen;
public AutoHuur(){
}
public void setHuurder(Klant nwH){
huurder = nwH;
}
public void setGehuurdeAuto(Auto nwGA){
gehuurdeAuto = nwGA;
}
public Auto getGehuurdeAuto(){
return gehuurdeAuto;
}
public Auto getPrijs(){
return prijs;
}
public void setAantalDagen(Integer nwD){
aantalDagen = nwD;
}
public String toString(){
String s = "";
if (gehuurdeAuto == null){
s = s + "er is geen auto bekend\n"; }
else {
s = s + gehuurdeAuto; }
if (huurder == null){
s = s + "er is geen huurder bekend\n"; }
else {
s = s + huurder; }
if (aantalDagen == null){
s = s + "aantal dagen: 0"; }
else {
s = s + "aantal dagen: " + aantalDagen; }
if (prijs == null){
s = s + " en dat kost 0.0"; }
else {
s = s + " en dat kost" + prijs; }
return s;
}
}
Auto.class:
public class Auto {
private String type;
private Double prijsPerDag;
public Auto(String tp, Double nwPr){
type = tp;
prijsPerDag = nwPr;
}
public void setPrijsPerDag(Double prPd){
prijsPerDag = prPd;
}
public Double getPrijsPerDag(){
return prijsPerDag;
}
public String toString(){
String s = type + " met prijs per dag: " + prijsPerDag + "\n";
return s;
}
}
In AutoHuur.class you can get your prijsPerDag variable from Auto.class using an Auto object, e.g.:
gehuurdeAuto.getPrijsPerDag()
You can calculate the price:
aantalDagen * gehuurdeAuto.getPrijsPerDag()
Is this what would you like to do?
You have to remove the first System.out becasuse in Main.java your instance AutoHuur is empty, so when your want to print the result , the out will be values empty.
The variable prijs is an object, which is initialized to null when an instance of AutoHuur is created. Since prijs is never set, it is always null.
That's why prijs == null always evaluates to true.
You need to set prijs somewhere.
It seems that you need to work on your design desicions. You are, for example, using an Auto class name, while it is in fact a link between a daily charge and a car type. If each link is represented by such an object (in your case Auto), then it absolutely makes no sense to have more than one instance.
For example,
new Auto("Peugeot", 40.0);
new Auto("Peugeot", 40.0);
is technically perfectly valid, but it is just not logical.
Furthermore, if a class holds data of some kind, then it's good to delegate operations upon that data also to that class.
class Auto {
private String type;
private double pricePerDay;
public double calculateTotalPrice(int numberOfDays) {
return numberOfDays * this.pricePerDay;
}
}
Related
Here's an article on Dozer: https://www.baeldung.com/dozer. It's a mapper that uses reflection to map same-name fields from one object to another (of a completely unrelated class).
I was wondering if this works flexibly with private fields, getters, and setters. That is,
Will private String a map to another object's private String a without either having any getters or setters?
What if only one side has a getter or setter (and the private field is named something different to make sure it's not directly accessing private fields)?
What if one has a getter and the other has a setter for totally mismatching private fields? (But the getter and setter names match.)
I wrote a test program to run in https://www.jdoodle.com/online-java-compiler:
import org.dozer.DozerBeanMapper;
public class Main {
public static class MySource {
// a -> a
private String a;
// getB() -> b
private String hidden_b;
public String getB() { return hidden_b; }
// c -> setC(c)
private String c;
// getD() -> setD(d)
private String hidden_d;
// proper getters and setters on both sides
private String proper;
public String getProper() { return proper; }
// public void setProper(String proper_) { proper = proper_; }
public MySource() {
a = "A Room with a View";
hidden_b = "The Bridge of San Luis Rey";
c = "Civilwarland in Bad Decline";
hidden_d = "Darkness at Noon";
proper = "This should copy, at minimum.";
}
public void print() {
System.out.println("Source");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("hidden_b = " + hidden_b);
System.out.println("c = " + c);
System.out.println("hidden_d = " + hidden_d);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static class MyTarget {
private String a;
private String b;
private String hidden_c;
private String hidden_e;
public void setC(String param) { hidden_c = param; }
public void setD(String param) { hidden_e = param; }
private String proper;
// public String getProper() { return proper; }
public void setProper(String proper_) { proper = proper_; }
public MyTarget() {}
public void print() {
System.out.println("Target");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("hidden_c = " + hidden_c);
System.out.println("hidden_e = " + hidden_e);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static void main(String args[]) {
MySource s = new MySource();
s.print();
System.out.println("Now dozing...");
System.out.println("");
MyTarget t = new DozerBeanMapper().map(s, MyTarget.class);
t.print();
}
}
Note that to run the above code you must add a maven dependency:
Group ID: net.sf.dozer
Artifact ID: dozer
Version: 5.5.1
And also you must try executing a few times because of random timeouts depending on whether the dependency loads fast enough.
Anyway, my output was:
Source
================================
a = A Room with a View
hidden_b = The Bridge of San Luis Rey
c = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper = This should copy, at minimum.
Now dozing...
Target
================================
a = null
b = null
hidden_c = null
hidden_e = null
--------------------------------
proper = This should copy, at minimum.
So, it appears Dozer only works through a getter on the source and a setter on the target, which is disappointing. Or, I'm not using it correctly!
Is there a way to make Dozer more flexible? Or, another mapper library that can achieve this?
Okay, here are my findings. Hopefully this helps someone.
Dozer 5.5.1 was supposed to be able to do this via "class-level is-accessible." However, there was a bug. It was fixed for future releases, e.g. Dozer 6.1+. (The package moved to a new group, org.github.dozermapper.) The steps were a little complicated though, and eventually I gave up to try ModelMapper, which was much nicer. So here's my code.
Include this package:
Group ID: org.modelmapper
Artifact ID: modelmapper
Version: 2.3.2
Here's how to use it:
import org.modelmapper.ModelMapper;
import org.modelmapper.config.Configuration;
public class Main {
public static class MySource {
// a -> a
private String a;
// getB() -> b
private String hidden_b;
public String getB() { return hidden_b; }
// c -> setC(c)
private String c;
// getD() -> setD(d)
private String hidden_d;
// proper getters and setters on both sides
private String proper;
public String getProper() { return proper; }
// public void setProper(String proper_) { proper = proper_; }
public MySource() {
a = "A Room with a View";
hidden_b = "The Bridge of San Luis Rey";
c = "Civilwarland in Bad Decline";
hidden_d = "Darkness at Noon";
proper = "This should copy, at minimum.";
}
public void print() {
System.out.println("Source");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("hidden_b = " + hidden_b);
System.out.println("c = " + c);
System.out.println("hidden_d = " + hidden_d);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static class MyTarget {
private String a;
private String b;
private String hidden_c;
private String hidden_e;
public void setC(String param) { hidden_c = param; }
public void setD(String param) { hidden_e = param; }
private String proper;
// public String getProper() { return proper; }
public void setProper(String proper_) { proper = proper_; }
public MyTarget() {}
public void print() {
System.out.println("Target");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("hidden_c = " + hidden_c);
System.out.println("hidden_e = " + hidden_e);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static void main(String args[]) {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
MySource s = new MySource();
s.print();
System.out.println("Now dozing...");
System.out.println("");
MyTarget t = modelMapper.map(s, MyTarget.class);
t.print();
}
}
Here's my output:
Source
================================
a = A Room with a View
hidden_b = The Bridge of San Luis Rey
c = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper = This should copy, at minimum.
Now dozing...
Target
================================
a = A Room with a View
b = The Bridge of San Luis Rey
hidden_c = Civilwarland in Bad Decline
hidden_e = null
--------------------------------
proper = This should copy, at minimum.
The fourth case didn't copy over but I don't really care about that case. I think it can easily achieved with a different ModelMapper configuration though. Maybe try LOOSE copying. Or worst case, manually bind the getter and setter methods in the config.
Dozer by default uses getters and setters, however you can tell Dozer (via mapping) to access the fields directly
http://dozer.sourceforge.net/documentation/custommethods.html
BTW, Dozer 5 and 6 contains an API based mapping as well.
Edited the getTypeString method in the Flowers class now I just get the pointer to the object
I'm working on a project for one of my classes. I haven't worked with HashMap before and I need to use one. In this java class I'm trying to print out the full description that I have set. But it wont print the HashMap value from the key. I have tried to use some code from my book, but with no luck.
This is the class that is calling the class that has the HashMap:
public class Garden
{
private Gardener gardener;
private Tools tools;
private Flowers flowers;
/**
* Constructor for objects of class Garden
*/
public Garden()
{
gardener = new Gardener();
tools = new Tools();
Flowers rose;
rose = new Flowers("a beautiful red flower");
rose.setFlower("red", rose);
System.out.println(rose.fullDescription());
}
}
Edited the getTypeString method
This is the class that is using the HashMap:
import java.util.Set;
import java.util.HashMap;
public class Flowers
{
private String fDescription;
private HashMap<String, Flowers> flowers;
/**
* Constructor for objects of class Flowers
*/
public Flowers(String fDescription)
{
this.fDescription = fDescription;
flowers = new HashMap<String, Flowers>();
}
public void setFlower(String color, Flowers type)
{
flowers.put(color, type);
}
public String flowerDescription()
{
return fDescription;
}
public String fullDescription()
{
return "The "+ getTypeString() + " is " + fDescription;
}
private String getTypeString()
{
String des = "";
Collection<Flowers> vals = flowers.values();
for(Flowers f : vals){
des += f;
}
return des;
}
}
The problem, I think, is in the getTypeString() function. Can anyone point me in the right direction?
Edit
I removed the getTypeString method and edited the fullDescription method:
public String fullDescription()
{
return "The "+ type + " is " + fDescription;
}
now I'm trying to get the 'HashMap' to print the objects like so:
"Flower [type= type, description= Description "]"
using thes methods:
public static void printHashMap()
{
System.out.println("hashmap: " + flowers);
}
#Override
public String toString()
{
return "Flower [type=" + type + ", description=" + fDescription ]";
}
From your post, what I have understood is that you want to print the description of flowers. So I think you can try something like:
private String getTypeString(){
String des = "";
Collection<String> vals = flowers.values();
for(String f : vals){
des = des + f.flowerDescription();
}
return des;
}
Override the toString method in your class
Declare a toString method with the following modifiers and return type:
#Override
public String toString() {
return this.fDescription;
}
Implement the method so that it returns a string.
Ok so I'm trying to get a better understanding of how to return a private variable from a class that I have created. I've only provided a small snippet of my main program to explain my question, so if more information is needed please let me know. My goal is to return a string from the class (working great), but also be able to return the private variables individually as needed (example used below is "flight_number").
public class Flights {
private String dest_city, dest_state, departureDate, departureTime;
private int flight_number;
public Flights(String city, String state, String dDate, String dTime, int flightNumber) {
dest_city = city;
dest_state = state;
departureDate = dDate;
departureTime = dTime;
flight_number = flightNumber;
}
public String toString() {
return "Flight number: " + flight_number + " Destination: " + dest_city + "," + dest_state + " Departing on:" + departureDate + " at" + departureTime + ".";
}
}
public class dummy {
public static void main(String[] args) {
// Uses the constructor to set values
Flights flight1 = new Flights("Houston", "Texas", "12/20/2014", "12:40 pm", 100);
System.out.println(flight1);
System.out.println(flight_number); // Error: `flight_number` cannot be resolved to a variable.
}
}
You need to add a public getter in Flights and call it from main:
public class Flights {
// all the private fields
public int getFlightNumber() {
return this.flight_number;
}
}
In Main:
public static void main(String[] args) {
Flights flight1 = new Flights("Houston", "Texas"); //...
System.out.println(flight1);
System.out.println(flight1.getFlightNumber()); // call the getter
}
You should start with an editor like eclipse and that should help you get started quickly. Getters and Setters is what you need, but start with Eclipse and you should do better.
I have to declare a parameter on my method final to access it through a Runnable but can I still access the methods? I need to edit the object a bit. I can't seem to find anything that can help me with this question, so hopefully this isn't a stupid question. Thanks in advanced!
An object is not final, but its reference is. So you can easily access its methods (if any) to modify the object.
You can change the state of the object, even if it is marked final. When you mark a reference variable final, you can't reassign it to another object, but you can definitely change the state of the object to which it is already referring by calling its methods.
Yes you can. Check this example
public class SampleA
{
private static final SampleB sampleB = new SampleB();
public static void main(String[] args)
{
System.out.println( sampleB.toString() );
sampleB.setM1( "1" );
System.out.println( sampleB.toString() );
}
}
public class SampleB
{
private String m1;
private String m2;
public String getM1()
{
return m1;
}
public void setM1(String m1)
{
this.m1 = m1;
}
public String getM2()
{
return m2;
}
public void setM2(String m2)
{
this.m2 = m2;
}
public String toString()
{
final String TAB = " ";
String retValue = "SampleB ( "
+ "m1 = " + this.m1 + TAB
+ "m2 = " + this.m2 + TAB
+ " )";
return retValue;
}
}
I'm currently trying to use jasper to help me create reports. I have the information and data that I want displayed in this method:
private void writeToFile(final List<ScenarioLoadModel> sceneLoadModel) throws Exception {
final BufferedWriter bw = new BufferedWriter(new FileWriter("/Uma/nft/result.psv"));
for (final ScenarioLoadModel slm : sceneLoadModel) {
bw.write(slm.getScenarioId() + PSP + slm.getScenarioId() + PSP + slm.getScenarioConfig().getName() + PSP + slm.getLoad() + PSP + "" + EOL);
if (!slm.getScenarios().isEmpty()) {
final int tempCount = slm.getScenarios().get(0).getTemplates().size();
final int sceneCount = slm.getScenarios().size();
for (int tempIdx = 0; tempIdx < tempCount; tempIdx++) {
String id = null;
int pass = 0;
int fail = 0;
final Map<String, BigDecimal> metricMap = new HashMap<String, BigDecimal>();
final DefaultStatisticalCategoryDataset dataset = new DefaultStatisticalCategoryDataset();
for (int sceneIdx = 0; sceneIdx < sceneCount; sceneIdx++) {
final Template temp = slm.getScenarios().get(sceneIdx).getTemplates().get(tempIdx);
if (temp.isError()) {
fail++;
} else {
pass++;
}
if (sceneIdx == 0) {
id = temp.getId();
}
final MetricGroupModel mgm = slm.getScenarios().get(sceneIdx).getMetricGroupModel().get(tempIdx);
if (mgm != null) {
for (final MetricModel mm : mgm.getMetricModel()) {
for (final MetricValue mv : mm.getMetricValue()) {
dataset.add(mv.getValue(), new BigDecimal(0.0), mv.getType(), id);
}
}
}
}
final TemplateConfig tc = TemplateManager.getTemplateConfig(id);
bw.write(slm.getScenarioId() + PSP);
bw.write(id + PSP + tc.getName() + PSP + 1 + PSP + pass + "/" + fail);
for (final Object row : dataset.getRowKeys()) {
final Number mean = dataset.getValue((String) row, id);
bw.write(PSP + row + PSP + mean);
}
bw.write(EOL);
}
}
}
bw.close();
}
From my understanding I create Beans and then put them all in a Bean Factory, to create my object that will be ready to be passed to iReport.
How can I put all this information into a Bean? I essentially want the bean to include the scenario/test case and whether or not it passed. (This is for test automation)
I tried to read your code to make a a best guess at what columns you would want, but with no context, I have no clue. All the bean is a pojo, with private fields and public getters and setters.
Assuming there is no grouping and essentially each ScenarioLoadModel will correspond to one row in the report you would end up with a bean like this:
public class ScenariaResults {
private String id;
private String name;
private String load;
private int passCount;
private int failCount;
public ScenariaResults(String id, String name, String load, int passCount,
int failCount) {
super();
this.id = id;
this.name = name;
this.load = load;
this.passCount = passCount;
this.failCount = failCount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLoad() {
return load;
}
public void setLoad(String load) {
this.load = load;
}
public int getPassCount() {
return passCount;
}
public void setPassCount(int passCount) {
this.passCount = passCount;
}
public int getFailCount() {
return failCount;
}
public void setFailCount(int failCount) {
this.failCount = failCount;
}
#Override
public String toString() {
return "ScenariaResults [id=" + id + ", name=" + name + ", load="
+ load + ", passCount=" + passCount + ", failCount="
+ failCount + "]";
}
}
So basically in the code you have above you build instances of ScenarioResults and add them to a list. Once you have the list, all you need to do is create a JRDataSource:
List<ScenarioResults> dataBeanList = ...call your method to get the list of results
//create the datasource
JRDataSource dataSource = new JRBeanCollectionDataSource(dataBeanList);
Now when designing the report in iReport it can be a little tricky to get the fields imported automatically. Basically first add your project with the bean to the classpath in iReports (could just point it to the bin folder or jar file`): Tools -> options -> classpath tab. Now follow these steps to add the fields.
Click the following icon:
Select the JavaBean Datasource tab.
Enter the classname of your bean. (ex. ScenarioResults)
Click Read attributes
Highlight the fields you want in the report and click Add Selected Field(s).
Click OK.
Now if you want to test what the report looks like with data, and not just an empty datasource, this is where the Factory comes in. It is only for testing while using iReport. You need to create a class that will essentially create a dummy data set for you. It should look something like:
import java.util.ArrayList;
import java.util.List;
public class ScenarioResultsFactory {
public static List<ScenarioResults> createBeanCollection() {
List<ScenarioResults> list = new ArrayList<ScenarioResults>();
list.add(new ScenarioResults("1", "test", "load", 10, 5));
//add as many as you want
return list;
}
}
Now you need to create a Datasource pointing to it in iReport.
Next to the Datasource dropdown in the toolbar click the icon with the tooltip `Report Datasources.
Click New.
Select JavaBeans set datasource. Click Next.
For name enter ScenarioResultsFactory.
For the Factory class you need to put the classname including package. So if the class is in the com package you should have com.ScenarioResultsFactory here.
For the static method put createBeanCollection if not already there.
Check the Use field description check box. Click Test to make sure it worked.
Click Save.