I have a problem with the following code:
Import java.util.ArrayList;
public class Car {
private String car;
private Car genCar = new Car();
ArrayList<String> allCars = new ArrayList<>();
public void setCar() {
genCar.setModel();
genCar.setCreator();
car = genCar.getModel() + "made by" + genCar.getCreator();
}
public void checkDouble() {
for (String search : allCars) {
while (search.equals(car)) {
setCar();
}
}
allCars.add(car);
}
public void repeater(){
for(int i = 0; i<52; i++){
setCar();
checkDouble();
}
}
}
Whenever I try to check for duplicates (which this code does) my program still puts the duplicate in the array when I actually try to avoid it this way.
Any solution so this works?
You do this:
public void checkDouble()
{
for (String search : allCars)
{
while (search.equals(car))
{
setCar();
}
}
allCars.add(car);
}
The problem with this is that, once you found a double, you generate a new car using setCar(), but you do not search the entire list again.
Do something like:
public void avoidDoubles()
{
while allCars.contains(car)
{
setCar(); // generate new, different car
}
allCars.add(car);
}
FWIW, you might want to change the name of some of the functions. I would call setCar() generateNewCar() or newCar().
I'm not sure what you're trying to do, but in checkDouble you are finding a duplicate and then adding it to the list.
If I understand you correctly, you don't need the loops, All you need to do is to use ArrayList.contains()
if(allCars.contains(someString))
{
System.err.println("Duplicate...");
} else
{
//setCar, addCar, etc.
}
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.
public class InventorySetDAO{
public LinkedList<CustomInventory> inventories = new LinkedList<>();
}
I am developing plugin that add/delete data in arraylist. and There's too much reference on the arrayList from other class.
Class InventoryItemModifier:
public class InventoryItemModifier {
InventorySetDAO inventorySetDAO;
public InventoryItemModifier(InventorySetDAO inventorySetDAO){
this.inventorySetDAO = inventorySetDAO;
}
public void addItem(ItemStack itemStack, ClickAction click, RequiredItems requiredItems) {
Bukkit.getPluginManager().callEvent(new ItemAddedEvent());
inventorySetDAO.getLastInventory().addItem(itemStack, click, requiredItems);
}
public void removeItem(ItemStack itemStack){
Bukkit.getPluginManager().callEvent(new ItemRemovedEvent());
inventorySetDAO.getLastInventory().removeItem(itemStack);
}
}
Class InventoryPlayerAccessor:
public class InventoryPlayerAccessor {
InventorySetDAO inventorySetDAO;
public boolean openPage(Player player) {
if (!inventories.isEmpty()) {
inventories.get(0).openInventory(player);
return true;
}
return false;
}
public boolean openPage(Player player, int index) {
if (!inventories.isEmpty()) {
if (index >= 0 && index < inventories.size()) {
inventories.get(index).openInventory(player);
return true;
}
}
return false;
}
}
I think there is risk of manipualte arrayList unproperly, so I think arrayList must be in a class and provide methods(add/insert/remove...) but if then there are too much responsibilities in that class.
I tried to seperate them into multiple classes, but it doesn't seem to solve this problem. is there a way to reduce reliance on arrayList, or efficient way to encapsulate arrayList?
To reduce each classes reliance on the underlying ArrayList (or just List), you could think about using the composite pattern instead of the DAO pattern. This would hide all/most of the logic to the InventorySet class.
class InventorySet {
private final List<CustomInventory> inventories = new ArrayList<>();
public void addItem() { }
public void removeItem() { }
}
Then, you can just keep your InventoryPlayerAccessor (maybe rename) but compose it of a InventorySet for easy access.
class InventorySetView {
void open();
}
I have a object graph which goes like this:
root
: childs (array)
: childs (array)
I am building a JSON response out of this so I need to loop through each collection creating code like this:
// code for root
// loop through direct root childs
for (Child child : childs) {
// Loop through the childs of the object in current context.
for (AnotherChild anotherChild : moreChilds) {
}
}
How do you avoid such code? It will be an arrow in the end. I could have created own methods for each level of for loop, but is that a good approach? Are there other approaches which is better?
If we are talking about this specific problem (building a JSON response) you use some kind of serializer like jackson or write a custom one. There is a relevant question on this topic https://stackoverflow.com/questions/338586/a-better-java-json-library
On the other hand for some other uses you can use a more functional approach like Guava or Lambdaj.
But when it comes done to big O complexity these are not much of a help there, so you may wanna try different approach if possible then.
That's a recursive structure, then you should use recursion to handle nesting. A depth first visit should do.
edit to interface JSON you would really follow the advice by #Mite Mitreski, for a recursive visit pseudocode sample:
void visit(Child tree) {
json_write_class(tree);
for (Attribute a : tree.attributes) {
json_write_attr(a);
if (tree.children != null) {
json_push_indent();
for (Child child : tree.children) {
visit(child);
}
json_pop_indent();
}
}
If you need more control, you could write kind of 'semantic actions' on nodes of that tree to establish the attributes, and implement the visitor pattern to output the data (more verbose than the first alternative).
Frequently helps to use the analogy of grammars and syntax trees, these are the most obvious sample we (as programmers) are used to.
I think you have a nasty design issue there, as the class that is doing all those loops knows a hell lot of the other classes (and thus breaking the Law of Demeter).
An approach I try to use (that I've learn from some very experienced developers) is to wrap collections (or arrays) in their own classes; and then create methods that iterate over the array/collection performing one operation. In this case, it could be calling another method in another class that wraps a collection.
In this way, each class has very little knowledge of what the other classes do (or the internals of the child objects).
Edit
Here's an example. Imagine that you have an account in a website similar to amazon. In that account, you have associated a few credit cards.
So, instead of having
class Account {
List<CreditCard> creditCards;
public CreditCard getPrimaryCard() {
//complex code to find the primary credit card
}
//lots of other code related to the account and credit cards
}
you can do
class Account {
CreditCards creditCards;
public CreditCard getPrimaryCard() {
creditCards.getPrimaryCard()
}
//lots of other code related to the account
}
class CreditCards {
List<CreditCard> creditCards;
public CreditCard getPrimaryCard() {
//complex code to find the primary credit card
}
public void addCard(CreditCard creditCard) {
//complex logic to validate that the card is not duplicated.
}
//lots of other code related to credit cards
}
In this way, Account doesn't need to know about how the creditCards are stored in memory (should it be a list? or a set? or get it from a remote webservice?)
Please bear in mind that this is a trivial example.
You could provide interface which all interested class should implement. That interface should provide method to converting a current object to JSON. See example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class JsonProgram {
public static void main(String[] args) {
Root root = new Root(Arrays.asList(new Child(Arrays.asList(
new AnotherChild(1), new AnotherChild(2)))));
System.out.println(root.toJSON());
}
}
interface JsonState {
String toJSON();
}
class Root implements JsonState {
private List<Child> childs = new ArrayList<Child>();
public Root(List<Child> childs) {
this.childs = childs;
}
#Override
public String toJSON() {
StringBuilder builder = new StringBuilder();
builder.append("{").append("\"childs\"").append(":[");
int index = 0;
for (Child child : childs) {
builder.append(child.toJSON());
if (index < childs.size() - 1) {
builder.append(",");
}
index++;
}
builder.append("]\"}");
return builder.toString();
}
}
class Child implements JsonState {
private List<AnotherChild> anotherChilds = new ArrayList<AnotherChild>();
public Child(List<AnotherChild> anotherChilds) {
this.anotherChilds = anotherChilds;
}
#Override
public String toJSON() {
StringBuilder builder = new StringBuilder();
builder.append("{").append("\"anotherChilds\"").append(":[");
int index = 0;
for (AnotherChild child : anotherChilds) {
builder.append(child.toJSON());
if (index < anotherChilds.size() - 1) {
builder.append(",");
}
index++;
}
builder.append("]}");
return builder.toString();
}
}
class AnotherChild implements JsonState {
private int value;
public AnotherChild(int value) {
this.value = value;
}
#Override
public String toJSON() {
StringBuilder builder = new StringBuilder();
builder.append("{").append("\"value\"").append(":\"").append(value)
.append("\"}");
return builder.toString();
}
}
Output:
{
"childs":[
{
"anotherChilds":[
{
"value":"1"
},
{
"value":"2"
}
]
}
]
}
But it is not a good solution. Instead of implementing Your own solution You should use some library which can do it for You. I recommend to You google-gson. For me is the best.
EDIT - GSON EXAMPLE
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonProgram {
public static void main(String[] args) {
Root root = new Root(Arrays.asList(new Child(Arrays.asList(
new AnotherChild(1), new AnotherChild(2)))));
Gson gson = new GsonBuilder().serializeNulls().create();
System.out.println(gson.toJson(root));
}
}
class Root {
private List<Child> childs = new ArrayList<Child>();
public Root(List<Child> childs) {
this.childs = childs;
}
#Override
public String toString() {
return Arrays.toString(childs.toArray());
}
}
class Child {
private List<AnotherChild> anotherChilds = new ArrayList<AnotherChild>();
public Child(List<AnotherChild> anotherChilds) {
this.anotherChilds = anotherChilds;
}
#Override
public String toString() {
return Arrays.toString(anotherChilds.toArray());
}
}
class AnotherChild {
private int value;
public AnotherChild(int value) {
this.value = value;
}
#Override
public String toString() {
return Integer.toString(value);
}
}
Above example create same output. For me this is a more elegant solution.
I have the following piece of code. I do not understand why its not working.
I'd really appreciate help on this.
import java.util.Scanner;
import java.io.*;
class ReadFiles {
String [] codes = new String[99];
int i = 0;
private Scanner readCodes;
public void openCodesFile() {
try {
readCodes = new Scanner(new File("C:/Users/Carlo/Desktop/Files/codes.txt"));
} catch (Exception e) {
System.out.println("Could not locate the data file!");
}
}
public void readCodesFile() {
while(readCodes.hasNext()) {
codes[i] = readCodes.nextLine();
i++;
System.out.println(codes[i]);
}
}
public void closeCodesFile() {
readCodes.close();
}
}
class NewHardware {
public static void main(String[] args) {
ReadFiles codesRead = new ReadFiles();
codesRead.openCodesFile();
codesRead.readCodesFile();
codesRead.closeCodesFile();
}
}
The output prints out "null" a bunch of times.
Also, I want to be able to not only print out the codes but use the codes array in the class NewHardware and manipulate it (print it out, truncate it, etc).
I was thinking of doing the following with readCodesFile():
public String readCodesFile() {
while(readCodes.hasNext()) {
codes[i] = readCodes.nextLine();
i++;
System.out.println(codes[i]);
}
return (codes[i]);
}
Or something but it hasn't worked just yet. Am I on the right track?
Oh, just wanted to add that the text contains the following:
G22
K13
S21
I30
H15
N23
L33
E19
U49
EDIT:
Thanks to Tony and Churk below to help me with my idiocy. I am accepting Tony's answer basically because he challenged me to think but Churk's answer is just as valuable.
For the second part of my question (where I asked about being able to use it in class NewHardware), I did the following:
class NewHardware {
public static void main(String[] args) {
ReadFiles codesRead = new ReadFiles();
codesRead.openCodesFile();
codesRead.readCodesFile();
for (int i = 0; i < 9; i++) {
System.out.println("\n\n" + codesRead.codes[i]);
}
codesRead.closeCodesFile();
}
}
This is of course not the final program code but this has helped me get the basic idea. Hope this helps others too.
codes[i] = readCodes.nextLine();
i++;
System.out.println(codes[i]);
You are printing codes[i++]
Look carefully at your readCodesFile() method. Look at every line. What is it doing? Can you explain it to us?
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);
}