Passing method of one class into another [duplicate] - java

This question already has answers here:
Passing a method from another class
(4 answers)
Closed 5 years ago.
My problem is that I need to getSymbol from Element class.
I would normally establish an object in PeriodicTable like this:
Element e = new Element();
then use e.getSymbol within method in order to use it for comparison.
So, in order to complete first task and print entire list of elements, I declared an array within PeriodicTable like this:
Element[] objects = new Element[ARRAY_SIZE];
I'm guessing I declared it correctly, as it does run entire list of elements.
Again, I am having problems getting getSymbol into my method in PeriodicTable.
Any helpful suggestions, please?
For this method, a user will input a symbol for an element. The method will search for the element and return its index (in the array). Then, it will use the index to display that single element and all of its other information, using the toString method from the Element class.
public int searchBySymbol(String sym)
{
int index = 0;
boolean found = false;
for (int i = 0; i < objects.length; i++)
{
objects[i] = objects.getSymbol;
}
while (index < objects.length && !found)
{
if (objects[index].equals(sym))
{
found = true;
}
else
{
index++;
}
}
if(found)
{
System.out.println("Found at position: " + index);
System.out.println(objects[index].toString());
}
else
{
System.out.println("Not found");
}
}

You definitely don't need two loops in there first of all, there are two solutions to this:
(Recommended) If searching Elements by symbol will be the your main way of looking up Elements, consider using a HashMap to contain the data rather than an Element array as HashMaps allow look up of objects by a key e.g. HashMap<String, Element>. Lookup the HashMap API or check this example: http://beginnersbook.com/2013/12/hashmap-in-java-with-example/
(Quick fix) Rather than using two loops to get the field and compare, in Java it is good practice to define accessor methods such as getSymbol() and return the field rather than directly accessing it. Using this method you can simplify your code into...
for (Element e : objects) {
if (e.getSymbol().equals(sym) {
return true;
}
}
//return false after the loop omits the need for an explicit boolean variable`
Edit: Usual for loop construct for index access. The index number is essentially tracked by the iterator variable int i so you do not need a separate variable to track it.
for (int i = 0; i < objects.length; i++) {
if (objects[i].getSymbol().equals(sym)) {
//print i to show index number
//print objects[i].toString();
return true;
}
}
//print not found...
return false;

Related

How do you find the index of the value(a String Value) from an arrayList? [duplicate]

For an Android app, I have the following functionality
private ArrayList<String> _categories; // eg ["horses","camels"[,etc]]
private int getCategoryPos(String category) {
for(int i = 0; i < this._categories.size(); ++i) {
if(this._categories.get(i) == category) return i;
}
return -1;
}
Is that the "best" way to write a function for getting an element's position? Or is there a fancy shmancy native function in java the I should leverage?
ArrayList has a indexOf() method. Check the API for more, but here's how it works:
private ArrayList<String> _categories; // Initialize all this stuff
private int getCategoryPos(String category) {
return _categories.indexOf(category);
}
indexOf() will return exactly what your method returns, fast.
ArrayList<String> alphabetList = new ArrayList<String>();
alphabetList.add("A"); // 0 index
alphabetList.add("B"); // 1 index
alphabetList.add("C"); // 2 index
alphabetList.add("D"); // 3 index
alphabetList.add("E"); // 4 index
alphabetList.add("F"); // 5 index
alphabetList.add("G"); // 6 index
alphabetList.add("H"); // 7 index
alphabetList.add("I"); // 8 index
int position = -1;
position = alphabetList.indexOf("H");
if (position == -1) {
Log.e(TAG, "Object not found in List");
} else {
Log.i(TAG, "" + position);
}
Output: List Index : 7
If you pass H it will return 7, if you pass J it will return -1 as we defined default value to -1.
Done
If your List is sorted and has good random access (as ArrayList does), you should look into Collections.binarySearch. Otherwise, you should use List.indexOf, as others have pointed out.
But your algorithm is sound, fwiw (other than the == others have pointed out).
Java API specifies two methods you could use: indexOf(Object obj) and lastIndexOf(Object obj). The first one returns the index of the element if found, -1 otherwise. The second one returns the last index, that would be like searching the list backwards.
There is indeed a fancy shmancy native function in java you should leverage.
ArrayList has an instance method called
indexOf(Object o)
(http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html)
You would be able to call it on _categories as follows:
_categories.indexOf("camels")
I have no experience with programming for Android - but this would work for a standard Java application.
Good luck.
the best solution here
class Category(var Id: Int,var Name: String)
arrayList is Category list
val selectedPositon=arrayList.map { x->x.Id }.indexOf(Category_Id)
spinner_update_categories.setSelection(selectedPositon)
Use indexOf() method to find first occurrence of the element in the collection.
The best way to find the position of item in the list is by using Collections interface,
Eg,
List<Integer> sampleList = Arrays.asList(10,45,56,35,6,7);
Collections.binarySearch(sampleList, 56);
Output : 2

Iterating over HashSet with for each

I'm trying to iterate over the Integer objects of a HashSet and I want to count the number of times an element occurs. this is my method so far
public int freq(int element) {
int numElements = 0;
for (int atPos : mySet){
if (mySet.atPos == element){ //says atPos cannot be resolved to a field
numElements++;
}
}
return numElements;
}
would it be better to use an iterator to iterate over the elements? How do I fix my
mySet.atPos
line?
This is where I initialize my HashSet
private HashSet <Integer> mySet = new HashSet<Integer>();
A Set cannot contain duplicate elements. Therefore you will always get a count of 0 or 1 for your element.
For any collection, you can get the frequency of the elements with:
public int freq(int element) {
return Collections.frequency(mySet, element);
}
Not sure you'd want to make a method out of it ...
Your issue is a simple misunderstanding of how you can use variables. int atPos and mySet.atPos do not refer to the same thing. The former refers to a local variable, the latter is looking for a public member of field of an instance of a set called the same thing.
You are trying to access this field:
public class HashSet
{
public int atPos; //<<<
}
but, when we think of it this way, obviously that field does not exist in HashSet!
All you need to do is get rid of mySet. and your code will work.
if (atPos == element){
numElements++;
}
Would it be better to use an iterator to iterate over the elements?
No, there's no benefit to using an iterator in this situation. A for each is more readable.
As others have noted, because sets will never contain duplicates, your numElements will actually only ever be one or zero. As such, you could actually write your function very compactly as:
public int freq(int element) {
if (myset.contains(element)) {
return 1;
}
else {
return 0;
}
}
Or even better using the ternary operator:
public int freq(int element) {
return myset.contains(element) ? 1 : 0;
}

How to remove a object inside an array list

I have searched a lot for this, and checked the posts that is provided as possible answers, and none seems to give me an answer.
I have this arraylist in which i store online users.
I can read from the user list and add to it.
Problem is, I cant seem to find out how I remove it.
I have tried
online.remove("MyUsername");
My class and initialiser is like this:
ArrayList<userOnline> online = new ArrayList<userOnline>();
class userOnline {
String userName;
String data1;
String data2;
String data3;
}
I thought it would find the object row with username and remove the row, or at least the username, but it removed nothing and does not give me any errors.
What can I do to make it work? Or what can I use as an alternative if this is not possible? A pointer to a doc explaining would be more than enough help!
Thanks!
Seemed like the solution was this, but this is not considered good practice
for (int i=0; i <online.size(); i++) {
if(online.get(i).userName.equals("username")) {
online.remove(i);
}
}
After a discussion and a lot of feedback seems like the only right way for java to handle this search and remove is,
Iterator<userOnline> it = online.iterator();
while (it.hasNext()) {
userOnline user = it.next();
if (currentLogin.equals(user.userName)) {
it.remove();
}
}
I couldn't find a dupe or a suitable doc, so here it is:
Use an Iterator:
for (Iterator<userOnline> iterator = online.iterator(); iterator.hasNext();) {
if (iterator.next().getName().equals("MyUsername")) {
iterator.remove();
}
}
Basically, you can't compare apples and pears (String and userOnline) directly. Yes you could override equals, but it should really match all the properties, not just one.
A simple solution would be to search the List, comparing each objects userName property with the value you want an either return the index or object reference, which you could use to remove it.
Alternatively, you could use an Iterator and remove it as you search...
ArrayList<userOnline> online = new ArrayList<>();
userOnline newUser = new userOnline();
newUser.userName = "MyUsername";
online.add(newUser);
System.out.println(online.size());
Iterator<userOnline> it = online.iterator();
while (it.hasNext()) {
userOnline user = it.next();
if ("MyUsername".equals(user.userName)) {
it.remove();
}
}
System.out.println(online.size());
There's probably also a really cool "streams" based solution, but small steps ;)
You could create a function that takes in your list of users and finds the first occurence of a given name and removes it when it finds a user with the name given like so
public Array<userOnline> removeUserByName(Array<userOnline> users, String nameToFind)
{
for(int i = 0; i < users.size(); i++)
{
if(users.get(i).userName.equals(nameToFind))
{
users.remove(i);
return users;
}
}
return users;
}
You could also make this function part of the class you store your list of userOnline objects then you wouldn't have to pass the array into the function.
You must search through the userOnline objects contained within your ArrayList and either find the index of the match or a reference to the match. Once you have either of these, you can remove the object from the list using one of the overloaded remove() methods. Remember that by default, the equals method compares references.
The search can be as follows:
private userOnline findUserOnlineWithUsername(String username) {
Iterator<userOnline> it = online.iterator();
onlineUser olu = null;
while(it.hasNext()) {
olu = it.next();
if (olu.userName.equals(username)) { return olu;}
}
return null;
}
Iterate over the list to find the index of the element you are interested in:
int idx = -1;
for (int i = 0; i < online.size(); i++) {
if(online.get(i).userName.equals("MyUsername"))
{
idx = i;
}
}
Use this index to remove the relevant element:
if(idx != -1) {
online.remove(online[idx]);
}
This would only remove the first occurrence. You could put this code into a function and call repeatedly to find all occurrences.
Your code is asking to remove a String from a List of UserOnlines, you need to use the object reference for the remove(Object o) method, or you need to find out the index of the object you wish to remove and use the remove(int index) method. How are you adding your objects to the list? If you're using the list itself as a reference you'll need to create your own method to define what object "MyUserName" is supposed to be.

How to remove value from Array in Method?

I have written this method to remove a value (the account from the accounts array).
public boolean removeAccount(BankAccount accountNumber){
for(int i = accounts.length - 1; i >= 0; i--) {
if(accounts[i] == accounts.length+1) {
accounts.length;
}
return -1
}
Would this be a proper way to remove an element from an array?
The code you are using to remove element is wrong. Also, I would recommend you to use List.Since if you remove an element from array you will need to change the index to -1 for all the elements that comes after the removed element. Also, array will have a blank value which will cause problems.
Updating your code to List. It should be something like this -
public void removeAccount(BankAccount accountNumber,ArrayList accounts)
{
int length = accounts.size();
for(int i = 0; i<length; i++)
{
if(accountNumber.equals(accounts.get(i))) //*
{
accounts.remove(i);
break;
}
}
}
In you code you never compare the objects. you are comparing an object with integer.
Also, In your code at the first iteration of loop method will return -1.
You call accounts.length in each iteration two times. I don't think it is a good practice. You should store the length in a variable and use it.

Implementing an equals() method to compare contents of two 'bag' objects

I am working on a school assignment. The objective is to practice GUI's, clone() methods, and using/ modifying existing code. I am trying to write an equals method in the way the instructor desires-- by using a clone of the object, removing items from the bag (returns boolean based on success or failure to remove).
The bag is represented in an array, and should return true in cases such as {1,2,3} and {3,2,1}, ie order does not matter, only the number of each number present in the arrays.
Here is the issue
It works in most cases, however there is a bug in cases where the bags contain numbers as such: {1,1,2} and {1,2,2} and other similar iterations. It is returning true instead of false.
I believe it has something to do with the remove() method we are supposed to use. If i understand it correctly, it is supposed to put the value at the 'end' of the array and decrease the manyItems counter (this is a variable for number of items in the array, because array.length is by default in the constructor 10.)
The code is largely written by another person. We had to import the existing files and write new methods to complete the task we were given. I have all the GUI part done so i will not include that class, only the used methods in the IntArrayBag class.
A second pair of eyes would be helpful. Thanks.
public class IntArrayBag implements Cloneable
{
// Invariant of the IntArrayBag class:
// 1. The number of elements in the bag is in the instance variable
// manyItems, which is no more than data.length.
// 2. For an empty bag, we do not care what is stored in any of data;
// for a non-empty bag, the elements in the bag are stored in data[0]
// through data[manyItems-1], and we don�t care what�s in the
// rest of data.
private int[ ] data;
private int manyItems;
public IntArrayBag( )
{
final int INITIAL_CAPACITY = 10;
manyItems = 0;
data = new int[INITIAL_CAPACITY];
}
public IntArrayBag clone( )
{ // Clone an IntArrayBag object.
IntArrayBag answer;
try
{
answer = (IntArrayBag) super.clone( );
}
catch (CloneNotSupportedException e)
{ // This exception should not occur. But if it does, it would probably
// indicate a programming error that made super.clone unavailable.
// The most common error would be forgetting the "Implements Cloneable"
// clause at the start of this class.
throw new RuntimeException
("This class does not implement Cloneable");
}
answer.data = data.clone( );
return answer;
}
public int size( )
{
return manyItems;
}
public boolean remove(int target)
{
int index; // The location of target in the data array.
// First, set index to the location of target in the data array,
// which could be as small as 0 or as large as manyItems-1; If target
// is not in the array, then index will be set equal to manyItems;
for (index = 0; (index < manyItems) && (target != data[index]); index++)
// No work is needed in the body of this for-loop.
;
if (index == manyItems)
// The target was not found, so nothing is removed.
return false;
else
{ // The target was found at data[index].
// So reduce manyItems by 1 and copy the last element onto data[index].
manyItems--;
data[index] = data[manyItems];
return true;
}
}
//I added extra variables that are not needed to try to increase readability,
//as well as when i was trying to debug the code originally
public boolean equals(Object obj){
if (obj instanceof IntArrayBag){
IntArrayBag canidate = (IntArrayBag) obj; // i know this can be changed, this was required
IntArrayBag canidateTest = (IntArrayBag) canidate.clone(); //this was created
//as a clone because it was otherwise referring to the same memory address
//this caused items to be removed from bags when testing for equality
IntArrayBag test = (IntArrayBag) this.clone();
//fast check to see if the two objects have the same number of items,
//if they dont will return false and skip the item by item checking
if (test.size() != canidateTest.size())
return false;
//the loop will go through every element in the test bag it will
//then remove the value that is present at the first index of the test bag
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
int check = test.data[i];
//remove() returns a boolean so if the value is not present in each bag
//then the conditional will be met and the method will return false
boolean test1 = test.remove(check);
boolean test2 = canidateTest.remove(check);
if (test1 != test2)
return false;
}//end for loop
// if the loop goes through every element
//and finds every value was true it will return true
return true;
}//end if
else
return false;
}//end equals
}
I cannot see the big picture, as I havent coded GUIs in Java before, however, as far as comparing 2 int[] arrays, I would sort the arrays before the comparison. This will allow you to eliminate problem cases like the one you stated ( if sorting is possible), then apply something like:
while(array_1[index]==array_2[index] && index<array_1.length)
{index++;}
and find where did the loop break by checking the final value of index
Is it explicitly stated to use clone? You can achieve it easily by overriding the hashCode() for this Object.
You can override the hashCode() for this object as follows:
#Override
public int hashCode() {
final int prime = 5;
int result = 1;
/* Sort Array */
Arrays.sort(this.data);
/* Calculate Hash */
for(int d : this.data) {
result = prime * result + d;
}
/* Return Result */
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()){
return false;
}
return false;
}
If you want to continue using your implementation for equals to compare test and CandidateTest then also you can compute unique hashes and make decision based on the results.
Here is the code snippet:
/* Assuming that you have put size comparison logic on top
and the two objects are of same size */
final int prime = 31;
int testResult = 1;
int candidateTestResult = 1;
for(int i = 0; i < test.size(); i++) {
testResult = prime * testResult + test.data[i];
candidateTestResult = prime * candidateTestResult + candidateTest.data[i];
}
/* Return Result */
return testResult == candidateTestResult;
I believe the problem is in this line:
for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
The problem here is that test and canidateTest are the clones that you made, and you are removing elements from those bags. And any time you remove an element from the bag, the size will decrease (because you decrease manyItems, and size() returns manyItems). This means you're only going to go through half the array. Suppose the original size is 4. Then, the first time through the loop, i==0 and test.size()==4; the second time, i==0 and test.size()==3; the third time, i==2 and test.size()==2, and you exit the loop. So you don't look at all 4 elements--you only look at 2.
You'll need to decide: do you want to go through the elements of the original array, or the elements of the clone? If you go through the elements of the clone, you actually never need to increment i. You can always look at test.data[0], since once you look at it, you remove it, so you know test.data[0] will be replaced with something else. In fact, you don't need i at all. Just loop until the bag size is 0, or until you determine that the bags aren't equal. On the other hand, if you go through the elements of this.data (i.e. look at this.data[i] or just data[i]), then make sure i goes all the way up to this.size().
(One more small point: the correct spelling is "candidate".)
Maybe you should try SET interface
view this in detail :http://www.tutorialspoint.com/java/java_set_interface.htm
A set object cannot contains duplicate elements, so it's suitable for your assignment than build your own class.
For example:[1,1,2] and [1,2,2]
you can use this to test whether they are equal
arr1 = {1,1,2}
arr2 = {1,2,2}
Set<Integer> set = new HashSet<Integer>();
for(int i : arr1){//build set of arr1
if(set.contains(i)==false){
set.add(i)
}
}
for(int i:arr2){
if(set.contains(i)==false){
System.out.println('not equal');
break;
}
}
Hope this is helpful.

Categories