This is a sample test code I wrote to ensure what I know is right
class Form {
List<Sample> samples;
List<Sample> sampleList;
public List<Sample> getSamples() {
return samples;
}
public void setSamples(List<Sample> samples) {
this.samples = samples;
}
public List<Sample> getSampleList() {
return sampleList;
}
public void setSampleList(List<Sample> sampleList) {
this.sampleList = sampleList;
}
void setInitialData() {
this.samples = new ArrayList<Sample>();
this.sampleList = new ArrayList<Sample>();
}
}
class Sample {
}
public class ListAddingAmbiguity {
public static void main(String[] args) {
Form form = new Form();
form.setInitialData();
Sample sample = new Sample();
form.getSamples().add(sample);
form.getSampleList().add(sample);
System.out.println(form.getSamples().size());
System.out.println(form.getSampleList().size());
}
}
The output coming is
1
1
And it is correct, samples and sampleList are two different references pointing to two different memory locations, so adding to samples won't change the size of sampleList.
But in my project code it is different, this is my Form class
public class InvoiceForm extends BaseActionForm {
private List<ProductTO> products;
private List<ProductTO> productList;
// getters and setters
}
This is the code in my Action class
private void setProductsToInvoice(InvoiceForm invoiceForm) throws Exception {
if(invoiceForm.getProducts() != null && !invoiceForm.getProducts().isEmpty()){
ProductTO productTO = new ProductTO();//ProductEntryHandler.getInstance().prepareProductsForInvoice();
invoiceForm.getProducts().add(productTO);
invoiceForm.getProductList().add(productTO);
}else {
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
}
}
Both the products and productList are having a size of 1 initially, so in the above code if block will execute. The commented portion is the earlier code. Even if it is the new code ProductTO productTO = new ProductTO(); or the old code ProductTO productTO = ProductEntryHandler.getInstance().prepareProductsForInvoice(); the problem is the same.
Like I said when execution comes to the method both the lists are having a size of 1. When the line invoiceForm.getProducts().add(productTO); is executed the size of products and productList size becomes 2, which is in conflict with my test code. Now when the nest line invoiceForm.getProductList().add(productTO); is executed both the list size is becoming 3. I don't know why its happening, can anybody help?
The following code else case in setProductsToInvoice set both products and productList to the same list:
List<ProductTO> productTOs = new ArrayList<ProductTO>();
productTOs.add(ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(productTOs);
invoiceForm.setProductList(productTOs);
The correct way, or at least the less incorrect way, is something like this:
ProductTO newProd =
ProductEntryHandler.getInstance().prepareProductsForInvoice());
invoiceForm.setProducts(new ArrayList<ProductTO>());
invoiceForm.getProducts().add(newProd);
invoiceForm.setProductList(new ArrayList<ProductTO>());
invoiceForm.getProductList().add(newProd);
I'd suggest an investigation to determine why there are two lists apparently being maintained in parallel in the first place. At first glance, it has a bit of a smell to it...
Related
I have a class to generate an Arraylist it all seems to work but in main it produces a compilation problem which I guess does not recognize my variable name as an ArrayList
public class Order {
//Attributes
private ArrayList<DessertItem> order;
//Constructors
Order(){
order = new ArrayList<DessertItem>();
}
//Methods
public ArrayList<DessertItem> getOrderList(){
return order;
}//end of getOrderList
public void add(DessertItem aItem) {
order.add(aItem);
}//end of add
public int itemCount() {
return order.size();
}//end of itemCount
}//end of class
public class DessertShop {
public static void main(String[] args) {
//create order
Order order = new Order();
//create obj and adding to the order
Candy c1 = new Candy("Candy Corn", 1.5, .25);
order.add(c1);
for (DessertItem item : order) {//here is where is marked the error
System.out.printf("%s.%n", item.getName());
}
Your code is hard to read. I'd recommend paying attention to formatting.
order is an Order, not an ArrayList. It has an ArrayList. That's what you want to iterate over.
Try this:
for (DessertItem item : order.getOrderList()) {
System.out.printf("%s.%n", item.getName());
}
A lot of your comments are clutter. I'd remove them.
I'd prefer a static type of List<DessertItem> for order. You can change the implementation for the List if you need to.
Here's my code. I apologize for the sloppiness but essentially what it's supposed to do is simulate the backwards learning algorithm used by switches. The handleInput method takes in the src and dest MAC addresses and a port number and adds the src MAC and port# as a HashMaps into an ArrayList. The whole method is useless right now because none of the HashMaps stay in the ArrayList for some reason. Any help is much appreciated!
public class Switching {
ArrayList<HashMap> switchTable = new ArrayList<HashMap>();
public String handleInput(String srcMacAddress, int portNumber, String destMacAddress){
String output = "";
HashMap tableEntry = new HashMap();
tableEntry.put(srcMacAddress, portNumber);
for (HashMap hm : switchTable) {
if (hm.containsKey(destMacAddress)) {
output += hm.get(destMacAddress).toString();
} else {
output += "Ports flooded";
}
}
switchTable.add(tableEntry);
return output;
}
public ArrayList<HashMap> getTable(){
return switchTable;
}
public class SwitchingTests {
#Test
public void testSwitching(){
new Switching().handleInput("123456", 12, "abcdef");
ArrayList<HashMap> switchingTable = new Switching().getTable();
Assert.assertEquals(switchingTable.toString(), "[{123456=12}]");
}
}
You are creating a Switching object and call handleInput(...) on it and then proceed to create a new Switching object and get its table.
You need to get the table from the one you already created.
public class SwitchingTests {
#Test
public void testSwitching(){
Switching switching = new Switching();
switching.handleInput("123456", 12, "abcdef");
ArrayList<HashMap> switchingTable = switching.getTable();
Assert.assertEquals(switchingTable.toString(), "[{123456=12}]");
}
}
inside your handleInput method you are creating new switchTable.
what you have to do is to change your line
switchTable = new ArrayList() to switchTable = getTable();
I read most of the other things on SO and I couldn't seem to find an answer.
Don't know how to write an add method. I'm getting a StackOverflowError. It seems to run infinitely which I am not sure why.
Also, just wanted to confirm that it is possible to write a print function that prints out everything in arraylist myPolygon right?
class IrregularPolygon{
private ArrayList <Point2D.Double> myPolygon;
// constructors
public IrregularPolygon() { }
// public methods
public void add(Point2D.Double aPoint) {
//System.out.println("in");
this.add(aPoint);
System.out.println("finished");
// for (Point2D.Double number : myPolygon) {
// System.out.println("Number = " + aPoint);
// }
}
}
public class App{
public static void main(String[] args){
IrregularPolygon polygon = new IrregularPolygon();
Point2D.Double point = new Point2D.Double(1.2, 2.3);
System.out.println(point);
polygon.add(point);
} // main
} // class
Calling this.add(aPoint) in add is a recursive call. This method calls itself, and there is no base case, so this results in a StackOverflowError once it recurses deeply enough.
It looks like you want to add it to the ArrayList, so change
this.add(aPoint);
to
myPolygon.add(aPoint);
In addition, you never initialized myPolygon, so it's null. Initialize it:
private ArrayList <Point2D.Double> myPolygon = new ArrayList<>();
I just started playing with Sencha's Ext GWT yesterday and I've hit a wall. I combined methods from their JSON loaded grid and their editable grid. As a test data set I'm using a list of Stargate Atlantis episodes hence the SGAEpisode which is defined as:
public class SGAEpisode extends BaseModel {
public SGAEpisode() {
}
public SGAEpisode(String season, String episode) {
set("season",season);
set("episode",episode);
}
public void setSeason(String season) {
set("season",season);
}
public String getSeason(){
return get("season");
}
public void setEpisode(String name) {
set("episode",name);
}
public String getEpisode() {
return get("episode");
}
public String toString() {
return "Season: " + get("season") + " episode: " + get("episode");
}
}
the onModuleLoad() starts off with...
ModelType type = new ModelType();
type.setRoot("seasons");
type.addField("Season","season");
type.addField("Episode","episode");
String path = GWT.getHostPageBaseURL() + "senchaapp/sgaepisodes";
final RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,path);
final MVProxy<String> proxy = new SProxy<String>(builder);
JsonLoadResultReader<ListLoadResult<SGAEpisode>> reader = new JsonLoadResultReader<ListLoadResult<SGAEpisode>>(type);
final BaseListLoader<ListLoadResult<SGAEpisode>> loader = new BaseListLoader<ListLoadResult<SGAEpisode>>(proxy,reader);
final ListStore<SGAEpisode> episodes = new ListStore<SGAEpisode>(loader);
so loader.load() works great, populating a grid, I can edit fields, but I don't see commitChanges() doing anything and I can't iterate over the ListStore "episodes" to gather changed or added values. Oh, and SProxy is just a DataProxy subclass to allow me to specify the season's JSON I'm loading into the grid.
If I try either
for(SGAEpisode episode : episodes) {
save(episode);
}
or
for(int i = 0; i < episodes.getCount(); i++) {
save(episodes.getAt(i));
}
I get an exception with the message "com.extjs.gxt.ui.client.data.BaseModel cannot be cast to com.mvsc.sencha.shared.SGAEpisode" Any idea what I'm doing wrong? Everything up to that point was defined/populated with SGAEpisodes.....
Addendum
Ok, so if I try
List<Record> modified = episodes.getModifiedRecords();
for(Record r : modified) {
ModelData md = r.getModel();
save(md.get("season"),md.get("episode"));
}
I can iterate, and get the modified values, but what's the point of having a ModelData subclass if I have to use the base class like this. Which makes me think I don't in fact have to..... little help?
Addendum 2 I tried subclassing BaseModelData instead with no success.
I know its an older post, I had the same issue. This is how I fixed it.
try iterating through the models in listStore.
for(SGAEpisode episode : episodes.getModels()) {
save(episode);
}
I have this ParkingLot.java
public class ParkingLot {
private final int size;
private Car[] slots = null;
List<String> list = new ArrayList<String>();
public ParkingLot(int size) {
this.size = size;
this.slots = new Car[size];
}
public List licenseWithAParticularColour(String colour) {
for (int i = 0; i < slots.length; i++) {
if (slots[i].getColour() == colour) {
System.out.println(slots[i].getLicense());
list.add(slots[i].getLicense());
return list;
}
}
return null;
}
}
I have created a ParkingLotTest.java as follows
public class ParkingLotTest {
private Car car1;
private Car car2;
private Car car3;
private Ticket ticket1;
private Ticket ticket2;
private Ticket ticket3;
private ParkingLot parkingLot;
private List<String> list = new ArrayList<String>();
#Before
public void intializeTestEnvironment() throws Exception {
this.car1 = new Car("1234", "White");
this.car2 = new Car("4567", "Black");
this.car3 = new Car("0000", "Red");
this.parkingLot = new ParkingLot(2);
this.ticket1 = parkingLot.park(car1);
this.ticket2 = parkingLot.park(car2);
this.ticket3 = parkingLot.park(car3);
this.list = parkingLot.list;
}
#Test
public void shouldGetLicensesWithAParticularColour() throws Exception {
assertEquals(, parkingLot.licenseWithAParticularColour("White"));
}
}
In the above Test Case, I want to check that the List is filled with the correct Licenses.
1. How do i create a field in the ParkingLotTest.java so that the List in the first class is same as list in the second class file.
First, I don't think you need a list on ParkingLot so your question actually doesn't make much sense :)
Second, just set up the expected result in each test method:
public class ParkingLotTest {
//...
#Test
public void shouldGetLicensesWithAParticularColour() throws Exception {
List<Car> expected = new ArrayList<Car>();
expected.add(...);
assertEquals(expected, parkingLot.licenseWithAParticularColour("White"));
}
}
And don't forget to also test unexpected values or special cases. For example:
#Test
public void shouldNotGetLicensesWithANullColour() throws Exception {
...
assertEquals(expected, parkingLot.licenseWithAParticularColour(null));
}
#Test
public void shouldNotGetLicensesWithAnUnknownColour() throws Exception {
...
assertEquals(expected, parkingLot.licenseWithAParticularColour("unknown"));
}
Some additional remarks:
I wouldn't use a Car[] for the slots but a List<Car>.
You don't really need the List<String> list in ParkingLot (and the current implementation of licenseWithAParticularColour is buggy).
I would use an Enum for the color.
However you want?
That's somewhat in jest, but however you normally build a List will do just fine - as long as it's consistent with what you want your tested interface list to be.
For this particular case, I'd recommend building a List<Car> as your test reference, then visiting each Car and parking it. You can then build the licenses list from that reference list, and compare it to the parking lot one. Just make sure your iteration direction is correct.
BTW, from what I see, I don't think things work the way they're supposed to work - good thing you're testing it.
Pascal's Answer worked for me.
#Pascal Again, I made this function:
public List getSlotNumbersWithAParticularColour(String colour) {
List<Integer> listOfTicketsWithAColour = new ArrayList<Integer>();
for (int i = 0; i < slots.length;) {
if (slots[i].getColour() == colour) {
listOfTicketsWithAColour.add(i);
}
return listOfTicketsWithAColour;
}
return null;
}
The fault is not in the for loop, adding an i++ is "dead-code" acc to Eclipse. Adding the i++ doesnt cause any difference.
And the corresponding test-case:
public void getSlotNumbersWithAGivenColour() throws Exception {
List<String> expected = new ArrayList<String>();
expected.add("0");
expected.add("3");
assertEquals(expected, parkingLot.getSlotNumbersWithAParticularColour("White"));
}
The test fails. The function only returns 0, instead of 0,3. Any idea why?