The searchDatabase method will accept a query string and search the ArrayList to see if the object contains the query(your search should be case-insensitive!) as the name or is of that object type (Hint: use instanceof to check for object type). It will return an ArrayList containing all of the values whose objects contain the query string.
I need to see if the query is the same as a class name (Such as Don/Talent/Overseer) and if it is then I print all objects of that type. If it's equal to a name in one of the objects then I just print that object out. I am confused as to what to do from here. I am looping through all goons in the Database and checking if they are instances of Don/Overseer/Talents and if they are then checking if the user query is equal to the object type and if it is print all of those objects but if it isn't then checking if it's equal to the name of any objects of type "Dom" in the arraylist.
protected ArrayList<Goon> searchDatabase(String query)
{
ArrayList<Goon> clone = new ArrayList<Goon>();
for(Goon a : goonDB)
{
if(a instanceof Don)
{
if(query.equalsIgnoreCase("don"))
{
}
else
{
if(a.getName().equals(query))
{
}
}
}
else if(a instanceof Overseer)
{
}
Your problem statement is ambiguous, here are my assumptions:
Goon is a parent class of Don/Talent/Overseer (They extend/implement
it).
You accept a query which stands for either object or a name
property in one of the implementation classes.
If query is a type name: return all objects of that type in a list.
Otherwise, check if it matches a name property: return all objects that have the same name property. (Although you said print that one object, I am going to ignore that, because then I would be returning null and more requirement questions arise)
I don't want to write it the code for you, because this looks like a homework assignment and you are much better off struggling a bit, but here is a logic that you would need to use to follow above assumptions:
I would first check if query is Don/Talent/Overseer. If it is then go through the list and add all objects that are of that type (instanceof) to your clone list . If it isn't, then go through the whole list and add those that have the name matching the query. Return the list.
Although I see you've already figured it out. I still want to post my answer :P (or else I made it for nothing). Maybe others who have the same problem can use it. I asumed that Don and Overseer implemented Goon by the way. And as a solution I just looped over the database checking if the query and the class name matched.
I also added a little main method to test the search code. And as you can see in the output only the Don's are printed.
package stackoverflow.question_26510341;
import java.util.ArrayList;
import java.util.Iterator;
public class Search {
static ArrayList<Goon> goonDB = new ArrayList<Goon>();
public static void main(String[] args){
goonDB.add(new Don());
goonDB.add(new Don());
goonDB.add(new Overseer());
ArrayList<Goon> list = searchDatabase("Don");
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
protected static ArrayList<Goon> searchDatabase(String query){
ArrayList<Goon> clone = new ArrayList<Goon>();
Iterator<Goon> iterator = goonDB.iterator();
Goon temp;
while(iterator.hasNext()){
if(query.equals("Don") && (temp = iterator.next()) instanceof Don){
clone.add(temp);
}else if(query.equals("Overseer") && (temp = iterator.next()) instanceof Overseer){
clone.add(temp);
}//etc...
}
return clone;
}
private static interface Goon{
}
private static class Overseer implements Goon{
}
private static class Don implements Goon{
}
}
Related
While I know that this code should work to return the index, for some reason it's skipping the if statement and going straight to the else, when I know that the name is within the array, with the array that I'm using for testing. Won't even print the "if - reading" line.
public int find(String name)
{
int index = 0;
for(int i = 0; i < this.shoppingItems.length;i++)
{
if(this.shoppingItems[i].equals(name))
{
System.out.println("If - Reading");
index = i;
}
else
{
index = -1;
}
}
System.out.println(index);
return index;
}
//Main
ShoppingItem[] items = new ShoppingItem[]{new ShoppingItem("Eggs",3.2),new ShoppingItem("Bread",2.8),new ShoppingItem("Bacon",9),new ShoppingItem("Peas",2),new ShoppingItem("Spinach",4),new ShoppingItem("Chocolate",8)};
ShoppingList itemList = new ShoppingList(items);
itemList.find("Bread");
"While I know that this code should work to return the index, for some reason it's skipping the if statement and going straight to the else"
Stop! Java is not wrong; your code is, and it shouldn't work. Your if statement is not being skipped; it's just that the condition is always false, because this.shoppingItems[i] is a ShoppingItem object, and you are comparing it with name, which is a string. A ShoppingItem object is never equal to a string.
Presumably, what you want to test is whether the ShoppingItem object's name is equal to that string. Presumably, your class has a getName method, so you should test:
if(this.shoppingItems[i].getName().equals(name)) {
// ...
}
This is a common kind of programming error, perhaps because it's often acceptable in natural language to say one thing when you mean something closely related; e.g. you might say "I asked the help desk" when really you asked a person at the help desk, you did not ask the desk itself. This is a bit like that; you want the item's name to equal name, not the item itself.
Unless you are compelled to use arrays, you can make things much easier by using lists. They have quite a few useful features.
List<String> items = List.of("bread", "juice", "eggs", "milk");
System.out.println(find("eggs"));
System.out.println(find("butter"));
public int find(String name) {
return items.indexOf(name);
}
Prints
2
-1
That method of the List interface pretty much negates the need to write you own method. I just did it for demonstration purposes.
This example was using a List of Strings and not ShoppingItem class. You could get a List<ShoppingItem> to work by overriding the equals method in your class (something you should get in the habit of anyway).
And here is a taste of how would do it with Stream (java 8+). It presumes list is a simple array of ShoppingItem.
public int find(String name) {
return IntStream.range(0, list.length).filter(
i -> list[i].item.equalsIgnoreCase(name)).findFirst().orElse(-1);
}
I'm having a bit of trouble in my head trying to solve this:
I'm working on a "rankList", an arrayList made of "Score". Score it's the object that has the following atributes: name,wins,loses,draws. My class Ranking has an ArrayList of Score objects. To create a new Score object I just use the name (and set the rest to 0 since it's new). However I'm trying to check if the player's name it's already in rankList I don't have to create new but sum a win or lose or draw.
I have been reading arround that I have to override equals then others say I have to override contains... It's getting a big mess in my head. My fastest solution would be to write an "for" that goes arround the arrayList and use the getName().equals("name"); however this is getting too messi in my code. I have checkPlayer (if the palyer is in the list):
public boolean checkPlayer(String playerName) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
return true;
}
}
return false;
}
then if I want to incrase the wins i have this :
public void incraseWins(String playerName) {
if (checkPlayer(playerName)) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
} else {
createPlayer(playerName);
//more for to get to the player i'm looking for...
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
}
So i guess there is a better way to do this... :/
ArrayList is not the right data structure here. To check if an element exists in the array you are searching the entire arraylist. Which means it's O(N).
To keep an array list is sorted order and do a binary search on it would definitely be faster as suggested in the comments. But that wouldn't solve all your problems either because insert into the middle would be slow. Please see this Q&A: When to use LinkedList over ArrayList?
One suggestion is to use a Map. You would then be storing player name, player object pairs. This would give you very quick look ups. Worst case is O(log N) i believe.
It's also worth mentioning that you would probably need to make a permanent record of these scores eventually. If so an indexed RDBMS would give you much better performance and make your code a lot simpler.
Try using a hashtable with a key, it would be much more efficient!
e..Why not using map<>.
a binary search is good idea if you must use List,code like this
List<Method> a= new ArrayList<>();
//some method data add...
int index = Collections.binarySearch(a, m);
Method f = a.get(index);
and class method is impl of Comparable,then override compareTo() method
public class Method implements Comparable<Method>{
........
#Override
public int compareTo(Method o) {
return this.methodName.compareTo(o.getMethodName());
}
if you don't want use binsearch,CollectionUtils in commons can help you
CollectionUtils.find(a, new Predicate() {
#Override
public boolean evaluate(Object object) {
return ((Method)object).getMethodName().equals("aaa");
}
});
in fact CollectionUtils.find is also a 'for'
for (Iterator iter = collection.iterator(); iter.hasNext();) {
Object item = iter.next();
if (predicate.evaluate(item)) {
return item;
}
}
I currently have 3 classes, a main class containing a GUI, and the fnameTxtField, a customer class containing the data, and a customerList class which gathers the data from the customer class, and puts it into an array list.
Quick fix: Refactor your method to have the following signature public void searchCustomer(String text) { ... } and call it with
searchCustome(fnameTxtField.getText()).
Then you could use the variable "text" in your method, so the line
if (search.returnFamilyName().equals(fnameTxtField.getText))
changes to
if (search.returnFamilyName().equals(text))
(Or don't have any parameters at all and add the [probably] missing parentheses to fnameTxtField.getText)
Where you are using fnameTxtField.getText, Java is expecting you to declare a method parameter (kind of like declaring a variable). A parameter is information that your method is told about for one particular execution, instead of having to find out on its own.
So you are right in thinking you want something like this:
public void searchCustomer(String familyName) {
for (int i = 0; i < customer.returnID(); i++) {
customer search = search.get(i);
if (search.returnFamilyName().equals(familyName)) {
System.out.println("Index: " + i);
//removed return i;
return;
}
}
}
Then at the point of invocation (method call) specify that you want to use the value in your text field:
//...
searchCustomer(fnameTxtField.getText());
I have a class called Paragens like this:
public class Paragens {
static int contadorParagens = 1;
String nomeParagem;
int id;
public Paragens(String nomeParagem) {
this.nomeParagem = nomeParagem;
this.id = contadorParagens++;
}
// getters and setters for nomeParagem
}
Every Paragens object has a name and an Id.
This class has a main method where I create several Paragens objects and store them inside an ArrayList like this:
public static void main(String[] args) {
ArrayList<Paragens> paragens = new ArrayList<Paragens>();
paragens.add(new Paragens("name1");
// ... add more paragens
}
This is working ok. If I insert a bunch of paragens and print them I can see tat is all ok.
What I am trying to do is to ask the user to input a paragem name and then I want to see if that paragem is already in the ArrayList.
String name;
System.out.println("Insert paragem name: ");
pickName = sc.nextLine();
System.out.println(paragens.contains(pickName));
What am I doing wrong?
contains checks to see if the list contains the actual thing you handed it. In this case, you're passing in a String name, but comparing it to Paragem instances. contains can't magically guess that it's supposed to look at a given property on the Paragem instances to compare the string.
You can easily loop the list to find out for yourself:
boolean found = false;
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) { // Or use an accessor function for `nomeParagem` if appropriate
found = true;
break;
}
}
...or as a function:
boolean containsParagemWithName(ArrayList<Paragem> paragems, String pickName) {
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) {
return true;
}
}
return false;
}
Well, you need to implement the contains method yourself. Do a for loop over the entire array and check if the name of one of the elements is equal with what you're trying to add. If not, add a new Paragens(pickName).
Objects by default are compared by their memory location. So if you have two Paragem with the same name, they are still not equal.
So either, you check the name of each one:
boolean checkDuplicate(String pickName) {
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) return true;
}
return false;
}
or implement (override) the equals method to compare names (you should be calling contains on a new Paragem object then instead of a String, though).
I'm fairly confident that there's no way this could work, but I wanted to ask anyway just in case I'm wrong:
I've heard many times that whenever you have a certain number of lines of very similar code in one batch, you should always loop through them.
So say I have something like the following.
setPos1(getCard1());
setPos2(getCard2());
setPos3(getCard3());
setPos4(getCard4());
setPos5(getCard5());
setPos6(getCard6());
setPos7(getCard7());
setPos8(getCard8());
setPos9(getCard9());
setPos10(getCard10());
setPos11(getCard11());
setPos12(getCard12());
There is no way to cut down on lines of code as, e.g., below, right?
for (i = 0; i < 12; i++) {
setPos + i(getCard + i)());
}
I'm sure this will have been asked before somewhere, but neither Google nor SO Search turned up with a negative proof.
Thanks for quickly confirming this!
No way to do that specifically in Java without reflection, and I don't think it would be worth it. This looks more like a cue that you should refactor your getcard function to take an integer argument. Then you could loop.
This is a simple snippet that shows how to loop through the getters of a certain object to check if the returned values are null, using reflection:
for (Method m : myObj.getClass().getMethods()) {
// The getter should start with "get"
// I ignore getClass() method because it never returns null
if (m.getName().startsWith("get") && !m.getName().equals("getClass")) {
// These getters have no arguments
if (m.invoke(myObj) == null) {
// Do something
}
}
}
Like the others stated, probably it's not an elegant implementation. It's just for the sake of completeness.
You could do it via reflection, but it would be cumbersome. A better approach might be to make generic setPos() and getCard() methods into which you could pass the index of the current item.
You need to ditch the getter/setter pairs, and use a List to store your objects rather then trying to stuff everything into one God object.
Here's a contrived example:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Foo {
public static class Card {
int val;
public Card(int val) {
this.val = val;
}
public int getVal() {
return val;
}
}
public static class Position {
int value;
public Position(Card card) {
this.value = card.getVal();
}
}
public static void main(String[] args) {
List<Card> cards = new ArrayList<Card>(Arrays.asList(new Card(1), new Card(2), new Card(3)));
List<Position> positions = new ArrayList<Position>();
for (Card card : cards) {
positions.add(new Position(card));
}
}
}
You can't dynamically construct a method name and then invoke it (without reflection). Even with reflection it would be a bit brittle.
One option is to lump all those operations into one method like setAllPositions and just call that method.
Alternatively, you could have an array of positions, and then just loop over the array, setting the value at each index.
Card[] cardsAtPosition = new Card[12];
and then something like
public void setCardsAtEachPosition(Card[] valuesToSet) {
// check to make sure valuesToSet has the required number of cards
for (i = 0; i < cardsAtPosition.length; i++) {
cardsAtPosition[i] = valuesToSet[i];
}
}
Reflection would be your only option for your example case.