Casting a Object to HashMap - java

I'm having trouble working out how to count instances of Values in a HashMap.
I have seen that there is methods attached to the Object class that look as if they are able to help me, so I've tried to cast those in to work but I must be doing something wrong somewhere.
If there's an easier way, I haven't found it yet. NB: Library is my HashMap.
public void borrowBooks(String id, String name, String sid, String sname) {
if((getKeyFromValue(Books, name).equals(id))&&(getKeyFromValue(Students, sname).equals(sid))){
if((Object)Library.countValues(sid)!=5){
Library.put(id, sid);
}
else{
System.out.println("You have exceeded your quota. Return a book before you take one out." );
}
}
}

Which doc are you looking at ? The Javadoc for Hashmap doesn't specify a countValues() method.
I think you want a HashMap<String, List<String>> so you store a list of books per student (if I'm reading your code correctly).
You'll have to create a list per student and put that into the HashMap, but then you can simply count the entries in the List using List.size().
e.g.
if (Library.get(id) == null) {
Library.put(id, new ArrayList<String>());
}
List<String> books = Library.get(id);
int number = books.size() // gives you the size
Ignoring threading etc.

First: There is (almost) no point in ever casting anything to Object. Since everything extends Object, you can always access the methods without casting.
Second: The way you're casting actually casts the return value, not the Library. If you were doing a cast that was really necessary, you would need an extra set of parentheses:
if(((Object)Library).countValues(sid) != 5)
Third: There is no countValues method in either HashMap or Object. You'll have to make your own.
This is the general algorithm to use (I'm hesitant to post code because this looks like homework):
initialize count to 0
for each entry in Library:
if the value is what you want:
increment the count

int count = 0;
for(String str : Library.values())
{
if(str == sid)
count++;
if(count == 5)
break;
}
if(count < 5)
Library.put(id, sid);
else
System.out.println("You have exceeded your quota. Return a book before you take one out." );

Related

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.

Creating an arraylist of nulls and then setting the index to an object

Really need help with this as a Patient is not getting set to replace the null. We have to create an arraylist of 50 nulls so the iterator goes through the list and if it finds a null it will set it to the patient. The problem is no patients are getting set to the null. We have to return the bed number at the end too.
protected int amountOfBeds = 50;
ArrayList<Patient> bedList = new ArrayList<Patient>(amountOfBeds);
public int admitPatient(Patient illPatient) {
int index = -1;
if(illPatient.getAge() > 0 && amountOfBeds > size()) {
//if it is null then set to patient
//if it not null then we assume its a patient so we skip
Iterator<Patient> itr = bedList.iterator();
try{
while(itr.hasNext()) {
int bedIndex = bedList.indexOf(itr.next());
if(bedList.get(bedIndex).equals(null)) {
bedList.set(bedIndex, illPatient);
index = bedIndex +1;
break;
}
}
}catch(NullPointerException e) {
e.getMessage();
}
}
return index;
}
Simple way to create 50 nulls list is this
List<Patient> list = Collections.nCopies(50, null);
quick way to find index of null is this
int i = list.indexOf(null);
In Java, an ArrayList is basically an array, that can change its size during execution time. Since you seem to have a fixed amound of beds, an array would probably be better here.
The constructor new ArrayList(50) doesn't create an ArrayList with 50 elements. It creates an empty ArrayList, but gives Java the "hint, that there will probably be inserted 50 elements into the ArrayList. If you don't give such a hint, the ArrayList starts with little space and is periodically made bigger, if it gets too small too accomodate all items you want to insert. This takes time, so if you already know how many items you will insert (even if you only know it approximately) this constructor makes your code faster.
However, you have to think if you really need to do this the way you just wanted to do. Whouldn't it be easier, to just have an empty ArrayList, to which you can add or delete elements just as you want to (without a complicated logic, which replaces null with an element. You could then just add if (array.size() >= 50) // it is full, so some special case may be needed here to make sure there are never more elements in the array than you want.

Implementing edit distance method using recursion results in object heap error

private static int editDistance(ArrayList<String> s1, ArrayList<String> s2) {
if (s1.size()==0) {
return s2.size();
}
else if (s2.size()==0) {
return s1.size();
}
else {
String temp1 = s1.remove(s1.size()-1);
String temp2 = s2.remove(s2.size()-1);
if (temp1.equals(temp2)) {
return editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone());
} else {
s1.add(temp1);
int first = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
s2.add(temp2);
s1.remove(s1.size()-1);
int second = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
s2.remove(s2.size()-1);
int third = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
if (first <= second && first <= third ) {
return first;
} else if (second <= first && second <= third) {
return second;
} else {
return third;
}
}
}
}
For example, the input can be ["div","table","tr","td","a"] and ["table","tr","td","a","strong"] and the corresponding output should be 2.
My problem is when either input list has a size too big, e.g., 40 strings in the list, the program will generate a can't reserve enough space for object heap error. The JVM parameters are -Xms512m -Xmx512m. Could my code need so much heap space? Or it is due to logical bugs in my code?
Edit: With or without cloning the list, this recursive approach does not seem to work either way. Could someone please help estimate the total heap memory it requires to work for me? I assume it would be shocking. Anyway, I guess I have to turn to the dynamic programming approach instead.
You clone() each ArrayList instance before each recursive call of your method. That essentially means that you get yet another copy of the whole list and its contents for each call - it can easily add-up to a very large amount of memory for large recursion depths.
You should consider using List#sublist() instead of clone(), or even adding parameters to your method to pass down indexes towards a single set of initial List objects.

Java, Create array if it doesn't already exist

I couldn't find anything on that while googling
so
I want to create an array only if it doesn't already exists.
EDIT: I mean not initialized
I know how to check for values in the array
Should be simple but I'm stuck
best regards
static long f(long n) {
int m = (int)n;
**if (serie == null) {
long[] serie = new long[40];
}**
if (n == 0) {
return 0;
}
else if (n==1) {
return 1;
}
else {
long asdf = f(n-1)- 2*(f(n-2)) + n;
return asdf;
}
}
something like that
a recursive function and I want to save the values in an array
You are trying to use the serie array but it is not yet declared. First declare it and then use it, as you want.
Are you looking for:
if (values == null)
{
values = new int[10];
}
or something like that? If not, please edit your question to provide more information.
EDIT: Okay, judging by the updated question, I suspect you ought to have two methods:
static long f(long n)
{
return f(n, new long[40]);
}
static long f(long n, long[] serie)
{
// Code as before, but when you recurse, pass in serie as well
}
(Note that your current code doesn't use serie at all.)
if(array==null){
//create new array
}
AFAIK, there are, if you use a variable in java, it is initialized. So you probably want to check if that variable, an array in this case, is null. Not only that, you can and probably should check if it is an array. Arrays are objects in java. So you could do something like this for an array:
if(!obj.getClass().isArray())

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