I have an ArrayList of object in my Fragment.
ArrayList<MenuListItem> menuItems = new ArrayList<MenuListItem>();
menuItems.add(new MenuListItem("Newsfeed", 20));
menuItems.add(new MenuListItem("FriendsRequest", 1));
menuItems.add(new MenuListItem("Messages", 2));
private class MenuListItem {
public String label;
public int count;
public MenuListItem(String label, int count) {
this.label = label;
this.count = count;
}
}
How can I find the index of object that has the label value "Messages" in my ArrayList from my Activity.
have you try to iterate through elements of menuItems?
something of this sort:
for(MenuListItem menuListItem : menuItems){
if (menuListItem.label.equals(<what you are looking for>){
<do something>
break; // in case when 1st occurence is sufficient
}
}
side note (not related make your members private and add accessors for them)
Edit: just noticed that you are looking for an index, what i have included is to get an MenuListItem what you can do is iterate and return index if you want.
try
String search="Messages";
for(int i=0;i<menuItems.size();i++){
if(menuItems.get(i).label.equalsIgnoreCase(search)){
System.out.println("Index " + i);
break;
}
}
public static int indexOf(final List<MenuListItem> menuItems, final String what) {
final int size = menuItems.size();
for (int i = 0; i < size; i++) {
final String label = menuItems.get(i).label;
if (label != null && label.equals(what)) {
return i;
}
}
return -1;
}
There's a easier and standard way to do this.
Eclipse
Right-click inside MenuListItem class and select Source -> Generate hashCode() and equals() once you are done generating the implementations of these methods. You can use ArrayList.indexOf(Object) to get the index of the item you are looking for.
IntelliJ or Android Studio
Right-click inside your editor and click on Generate and from the dialog that pops up, select hashCode() and equals().
The Collections framework has made things easier for you already. Why not leverage it instead of writing loops to find objects? :)
PS: This can be hand written, but this is something best left to the IDE. Because having too many attributes makes it tricky to get it right the first time.
Related
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;
}
}
First of all sorry if my English bad, its not my first language..
I'm working on and android app project, that needed to sort ArrayList of an object..so I made this method to deal with that...
Lets say that I have an object of Restaurant that will contain this data:
private String name;
private float distance ;
And I sort it using the value of the variable distance from lowest to highest:
public void sort(RArrayList<RestaurantData> datas) {
RestaurantData tmp = new RestaurantData();
int swapped;
boolean b = true;
while (b) {
swapped = 0;
for (int i = 0; i < datas.size()-1; i++) {
if (datas.get(i).getDistance() > datas.get(i+1).getDistance()) {
tmp = datas.get(i);
datas.set(i, datas.get(i+1));
datas.set(i+1, tmp);
swapped = 1;
System.err.println("Swapped happening");
}
}
if (swapped == 0) {
System.err.println("Swapped end");
break;
}
}
But when i try the program..the result of an ArrayList is still random, is there any problem with my logic to sort the ArrayList of an object..
Please Help...Thankyou..
Why not use the Collections.sort method?
Here's how you could do it in your project:
public void sort(RArrayList<RestaurantData> datas) {
Collections.sort(datas, new Comparator<RestaurantData>() {
#Override
public int compare(RestaurantData lhs, RestaurantData rhs) {
return lhs.getDistance() - rhs.getDistance();
}
});
}
The above solution is a bit "destructive" in the sense that it changes the order of the elements in the original array - datas. If that's fine for you go ahead and use it. Personally I prefer things less destructive and if you have the memory to spare (meaning your array is small) you could consider this solution which copies the array before sorting. It also assumes your RArrayList is an implementation of ArrayList or backed up by it:
public List<RestaurantData> sort(RArrayList<RestaurantData> datas) {
// Create a list with enough capacity for all elements
List<RestaurantData> newList = new RArrayList<RestaurantData>(datas.size());
Collections.copy(newList, datas);
Collections.sort(newList, new Comparator<RestaurantData>() {
#Override
public int compare(RestaurantData lhs, RestaurantData rhs) {
return lhs.getDistance() - rhs.getDistance();
}
});
return newList;
}
Another thing to consider is also to create a single instance of the Comparator used in the method, since this implementation will create one instance per call. Not sure if it's worth it though, because it will also be destroyed quite soon since the scope is local.
Here's the documentation for the Collections api
One last thing, the comparator simply needs to return a value less than 0 if the elements are in the right order, bigger than 0 if they're in the wrong order or 0 if they're the same. Therefore it seems to be that it's enough to simply subtract the distances of each restaurant. However, if this isn't the case, please implement the comparator suiting your needs.
I'm trying to make a small game like thing for school. It's designed to help you learn your times tables. What I want is for the multiplier of the table to be random each time (5x8 then 5x3 then 5x9 etc).
I've got the generating of the numbers in control with an array as can be seen below
public static Integer[] generateNumbers()
{
Integer[] arr = new Integer[12];
for(int j = 0; j < arr.length; j++)
{
arr[j] = j+1;
}
Collections.shuffle(Arrays.asList(arr));
System.out.println(Arrays.asList(arr));
return arr;
}
How can I make it so that every time the user clicks a button, the next number in the array is selected, baring in mind that the button is declared in another class, and the ActionListener is also declared elsewhere?
Oh and the array is available class-wide as the function is declared like this:
public static Integer[] arr = generateNumbers();
Thematic answer
public class UnicornFrame extends JFrame {
private Integer[] poneyArr = MyClassThatGeneratesNumbers.generateNumbers();
private int poneyCounter = 0;
private JButton poneyButton;
public void poneyInit() {
System.out.println("Unicorns are poney magical friends!");
poneyButton = new JButton("OMG! Ponies!");
// Java 8 Lambdas! Yey!
poneyButton.addActionListener(e -> {
if (poneyCounter >= poneyArr.length) {
poneyArray = MyClassThatGeneratesNumbers.generateNumbers();
poneyCounter = 0;
}
Integer selected = poneyArr[poneyCounter++];
System.out.println("OMG! I have selected " + selected);
});
// other stuff
add(poneyButton, BorderLayout.CENTER);
}
}
The button int he separate class is not needed, the action listener will communicate with your array whenever its clicked, the easiest way I see is to put a public method int the array's class, that takes an index, which then increments the index, and returns the element stored at it.
Have fun coding, but these assignments are meant for you to scratch your head, try writing some code, and let us know if it breaks, rather than asking for general answers.
I'm new to using OOP, I typically just put all my code in a single class and use methods. But I want to maintain state information and think classes are the best fit but I'm having trouble wrapping my head around it.
Say I have a list of items and I want to stop when the total sum of all previous items in the list equals X(in this case 10 so it takes item 1 + 2, then 2+3.etc..until it hits the threshold 10), I can use a method to calculate it but it involves me doing the entire process all over again when all I really need to do is increment by the last item and then see if my data exceeds the threshold. Here's my code so far but I know its not good because although it works its really just using the class as an independent method and recalculating on every loop. My goal is to,using this structure, reduce loops if not necessary to check thresholds.
Any suggestions?
Code:
public class LearningClassesCounter {
public static void main(String[] args) {
int[] list = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] data_list = new int[list.length];
for (int current_location = 0; current_location<list.length;current_location++) {
//can only put commands in here. Nothing above.
Counter checker = new Counter(data_list);
System.out.println(checker.check_data(current_location));
for (int i =0; i<100; i++){
if (checker.check_data(current_location) == false) {
break;
}
data_list[current_location] = (list[current_location]+1); //this is just a random function, it could be any math function I just put it in here to show that some work is being done.
}
}
//its done now lets print the results
for (Integer item : data_list) {
System.out.println(item);
}
}
}
class Counter {
private int[] data_list;
private int total_so_far;
// create a new counter with the given parameters
public Counter(int[] data_list) {
this.data_list = data_list;
this.total_so_far = 0;
}
public boolean check_data(int current_location) {
// TODO Auto-generated method stub
int total_so_far = 0;
//System.out.println(total_so_far);
for (int item : data_list) {
total_so_far = item + total_so_far;
if (total_so_far >= 10) {
break;
}
}
if (total_so_far>=10) {
return false;
} else {
return true;
}
}
}
I don't need anyone to fix my code or anything(I want to do it myself, the code is just to give an idea of what I'm doing). I'm more interested in the flaw in my logic and maybe a way for me to better think about designing classes so I can apply them to my own situations better.
So the solution is that you do not update the data_list directly. Instead have a setter method in the Counter class that takes the index and value to update. It updates the value in the array and also updates a count value.
Something like this:
class Counter{
private final int[] list;
private count = 0;
private final maxCount = 10;
public Counter(int[] list){
this.list = list;
}
public boolean updateValueAndCheckPastMax(int index, int value){
list[index] = value;
count += value;
return count >= maxCount;
}
}
You are way over thinking this, and a counter class is not really necessary in this case.
I'm also interested as to why you'd be doing this line:
data_list[current_location] = (list[current_location]+1);
Do you want your data_list to be the same as list, but each value is incremented by 1?
If you are merely trying to return a sub-array of the values that are < 10, i would suggest just doing this in a for loop, and using an int as a counter.
I guess the title of this questions says it all, or says nothing...
After couple of hours of googling, trying things and reinventing Java I decided to ask you.
I have this storage class:
class AppInfo implements Comparable<AppInfo > {
private String appname = "";
private String pname = "";
private String versionName = "";
//private int versionCode = 0;
private Drawable icon;
private String appdir = "";
private String appSize = "";
#Override
public int compareTo(AppInfo other) {
int compareAppsName = appname.compareToIgnoreCase(other.appname);
return compareAppsName;
}
}
I do what I do and eventually I get a List filled with objects.
Everything works great, ListView is populated with the right data...
Now I want to search a string (a certain pname) and see if it exists in the List and if it does, what's its position in the list (its index).
Tried creating another list with only the data I need.. tried Lists, HashMaps, LinkedHashMap, 2 dimensional arrays/arrayList... nothing did the trick...
Also tried iterating the list but couldn't figure out how to handle the elements I got.
Hopefully I make some sense and that's even possible.
Disclosure: Please bear with me, I am kinda new in Java.
I'm not entirely sure that I understand your question, but if you want to find the indices of the list elements with the given pname value, you can do something like this:
List<Integer> indices = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i++) {
String panme = list.get(i).getPname();
if (pname != null && pname.equals(expectedPname));
indices.add(i);
}
}
I just reread your question, and it sounds like you're only expecting the index to show up once. Sorry for the confusion. For that, you can use the same idea without the additional list:
int matchingIndex = -1;
for (int i = 0; i < list.size(); i++) {
String pname = list.get(i).getPname();
if (pname != null && pname.equals(expectedPname));
matchingIndex = i;
break;
}
}
If you just wanting to check the pname string you could add a getter method to your AppInfo class e.g.
public String getPname(){
return pname ;
}
then as you iterate through your list you can call .getPname to extract the string at the given position in the list.
m