Searching a Java LinkedList - java

I am trying to search through a Java LinkedList that uses a custom object called Name. I need to search on first name (My compareTo method in Name already compares last names because I need to use it to sort by last name). Name has an observer method called getFirstName().
I am not having any success in accessing first name from my LinkedList. This is what I want to do but this (obviously) doesn't work.
if (iterator.next().getFirstName().equals(inputSearch))
Can someone point me in the right direction?
This is the full method I am currently trying to write:
// Creating a method to search for a first name
static void searchName()
{
Scanner inData = new Scanner(System.in);
// Label to request input from user
System.out.println("Enter the first name that you would like to search for:");
// Setting variable to capture input
String inputSearch = inData.next();
// Creating an iterator to search through the list
iterator = list.iterator();
// While loop to search each entry
while (iterator.hasNext())
{
if (iterator.next().getFirstName().equals(inputSearch))
{
System.out.println("MATCH FOUND: " + iterator.next());
}
}
}

You're calling iterator.next() twice. The second time will advance past the item you want. Instead, save the return value from the first call to iterator.next() and use that.
while (iterator.hasNext())
{
Name item = (Name) iterator.next();
if (item.getFirstName().equals(inputSearch))
{
System.out.println("MATCH FOUND: " + item);
}
}
or, more idiomatically
for (Name item : list)
{
if (item.getFirstName().equals...
}

while (iterator.hasNext()) {
if (iterator.next().getFirstName().equals(inputSearch)) { //iterator.next()
System.out.println("MATCH FOUND: " + iterator.next()); //iterator.next()
}
}
Since you are calling next() twice, while printing it would be next object.
try storing whatever iterator.next() returns in its corresponding type and use it to compare and print if succeed.
ex:
while(iterator.hasNext(){
Name name=iterator.next();
if(name.getFirstName().equals(inputSearch)){
System.out.println("Match Found"+name);
}
}
This is what I see wrong. Not aware of anything else.

Related

Passing method of one class into another [duplicate]

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;

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.

java recursive linked list

private Node<T> recremoveFirst (Node<T> list, T element)
{
if (list == null)
return null;
else if(list.next == element)
return list.next;
else{
list.next = recremoveFirst(list.next, element);
return list;
}
}//calling recursive method
public void removeFirst(T element) {
recremoveFirst(head, element);
}
int choice;
Element elem;//constructor public Element (String name, int no)
LinkedList<Element> list = new LinkedList<Element>();
String name;
int number;
case 1 : // addFirst
System.out.print("Type name and number: ");
name = Cin.readString();
number = Cin.readInt();
list.addFirst(new Element(name,number));
break;
case 2 : // addLast
System.out.println("Enter name and number to add last element: ");
name = Cin.readString();
number = Cin.readInt();
list.addLast(new Element(name, number));
break;
case 3 : // removeFirst
list.removeFirst(elem);
When I'm trying to test this recursive method it shows me an error near list.removeFirst(elem);
and gives only suggestion initialize it even though it is initialized(if press initialize sets it to null). So I wonder what's is that I'm doing wrong.
Error mssage: Multiple markers at this line
- The local variable elem may not have been
initialized
- The constructor Element(Element) is
undefined
Because
Element elem;
could be null when
list.removeFirst(elem);
is executed.
So it will be
Element elem = null;
(You need to initialize it to use it.)
Anyway, i'm pretty sure you want something like this:
list.addFirst(elem = new Element(name,number));
So it
list.removeFirst(elem);
will remove the item added recently.
Anyway, are you sure you don't want to use removeFirstOccurrence ? Because removeFirst does a total different thing.
removeFirstOccurrence:
Removes the first occurrence of the specified element in this list (when traversing the list from head to tail). If the list does not contain the element, it is unchanged.
Anyway the reason you get this error, is not related to the recursion
Edit:
Well, you don't need any edit to addFirst since removeFirst will remove the first item in the list.
You just need to change
removeFirst(elem);
to
removeFirst();
In this case, if you don't use it in other places, you don't need anymore elem.

Trying to print an array

I need some help with java and returning a result from an array.
My array list stores orders from a restaurant (created by the Order Class). The Deliverylog Class (which creates the array lists) then has a method for adding the orders to an array list called waitingList.
Each order has a reference number aswell ass details of it delivery time and so on ..
What im trying to do , but havent got a clue is to , is to create a method with a parameter (int ref) that will search the array list for an item with the same reference number as the one entered. When it finds it it returns the order , otherwise it returns null.
Any help is appriciated.
code
/**
* Show a order.
* #param refnum The reference number of the order to be shown
*/
public void findOrderWaiting(int refnum)
{
if(refnum < 0) {
// This is not a valid reference number
}
else if(refnum <= numberOfOrders()) {
// This is a valid reference number
System.out.println(waitingList.get(refnum));
}
else {
// This is not a valid reference number
}
}
You know arrayList has a method to find an item inside:
//a is an arraylist
//filling the list here is omitted
//o is the object to find its index
int ind=a.indexOf(o);
int indexOf(Object o) is already-invented so you dont have to make a method. If you want this for learning purposes, you can search hashing techniques from internet but you are using arrayList and the easiest thing is the indexOf() method.
HashTable is more flexible by giving you freedom to search for an item or a key (you give key and get item or you give item and get its key)(key can be an object too!)
Well, you could loop through the array using a standard for loop:
for(int i=0; i<array.length; i++){
if(array[i].intPart == ref) return array[i];
}
return null;
Hope that helps!
for(String s: restaurentOrders){
if(s.equalsIgnoreCase()){
//You have it..
}
}
If u are storing your array/Arraylist in restaurentOrders. Hope it helps

How do I refer to the current object in an iterator

I am trying to implement a search method in a TreeSet. By using an iterator with a condtional I would like to be able to run through the set and print the object that matches the condition. However the way I am doing it at the moment is printing out the subsequent object rather than the current.
This is what I have so far:
public void getDetails() {
Iterator<Person> it = this.getPersonSet().iterator();
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
if (it.next().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Any help would be great
This is what you would want to do:
while (it.hasNext()) {
Person p = it.next();
if (p.getLast().toLowerCase().equals(last)) {
System.out.println(p);
}
}
How do I refer to the current object in an iterator
For the record, the Iterator API does not allow you to do this. There is no notion of a "current" object. The Iterator.next() method gives you the next object ... and moves on.
(The ListIterator.previous() and ListIterator.next() methods are analogous. Note that in the ListIterator case, method behaviour is documented in terms of a cursor that denotes a position before / between / after elements in the sequence being iterated.)
The solution is to assign the result of calling it.next() to a temporary variable, as described by the accepted answer.
I don't know for sure why the designers didn't include the notion of a "current" object in the API, but I can think of a few reasons:
It would make a typical1 Iterator object bigger; i.e. an extra field to hold the current object.
It would mean 1 extra method for an Iterator class to implement.
The notion of a current object does not fit well with the "cursor" model documented in the ListIterator interface ... and implied by the current Iterator design.
There is the issue of the Iterator "hanging onto" the current object. In some cases that will prevent from being GC'ed.
The large majority of iterator use-cases don't require a current object.
Also, there are other ways to deal with this.
Sounds like a good call ...
1 - This and other points don't apply equally to all implementations of the Iterator API. Indeed, in some cases the implementation of current() will be simple. But that is beside the point. Unless you make the proposed current() method an optional2 method (like remove()) every iterator implementation ... and by extension, every Map and Collection class ... has to provide this functionality, and deal with the issues, one way or another.
2 - Optional methods come with their own problems.
If you need an existing implementation, you can use the ones from Google Guava or Apache Commons Collections.
The other answers are easier for your simple problem, but if you need to pass the iterator around and keep track of the last item returned by next(), these would help.
Here is an example using Guava with the OP's code (assumging Person indeed has a String toLowerCase() method):
import com.google.common.collect.PeekingIterator;
import static com.google.common.collect.Iterators.peekingIterator;
public void getDetails() {
PeekingIterator<Person> it = peekingIterator(this.getPersonSet().iterator());
System.out.println("Enter First Name");
String first = in.next().toLowerCase();
System.out.println("Enter Second Name");
String last = in.next().toLowerCase();
while (it.hasNext()) {
// note the usage of peek() instead of next()
if (it.peek().getLast().toLowerCase().equals(last)) {
Person p = it.next();
System.out.println(p);
}
}
}
Hold the reference of the object in a separate var:
Person current = it.next();
current.methodOne();
current.methodTwo();
When you're done with the current value, re-assing it the next
...
// done?
current = it.next();
In a loop looks like:
while( it.hasNext() ) {
Person current = it.next();
current.doA();
current.doB();
current.doC();
}
the next() method returns the current object, like this:
private class IterSinglyLinked implements SimpleIterator<T> {
Element curr = head; // next element to return
public boolean hasNext() {
return curr != null;
}
public T next() throws Exception {
if (curr == null) throw new Exception("no more elements");
T data = curr.data;
curr = curr.next;
return data;
}
}
If it returns the next one rather than the current one, there will be no way to reach the very first one

Categories