I was asked to demonstrate a Singleton class design for my assignment. The version I submitted uses Strings and works fine, but I just can't get the reserveLane method to work properly with integers. Whenever I call the reserveLane method in the code below, it removes the element with the index of the integer passed into it instead of the element containing the value that matches the integer passed in. The program is supposed to print each message in the removeLane method once.
import java.util.*;
public class Race {
// store one instance
private static final Race INSTANCE = new Race(); // (this is the singleton)
List<Integer> lanes = new ArrayList<>();
public static Race getInstance() { // callers can get to
return INSTANCE; // the instance
}
private Race() {
lanes.add(1);
lanes.add(2);
}
public void removeLane(int lane) {
if(lanes.contains(lane)){
lanes.remove(lane);
System.out.println("Lane successfully reserved.");
} else {
System.out.println("Lane is already reserved.");
}
}
public static void main(String[] args) {
assignLane(1);
assignLane(1);
}
private static void assignLane(int lane) {
Race race = Race.getInstance();
race.removeLane(lane);
}
}
I'm wondering if I'm wasting my time trying to go this route or is there a way to fix it?
Integer integer = new Integer(lane);
lanes.remove(integer);
Your lanes is an arraylist of Integer objects, not int. Passing an int to Arraylist.remove(int index) will remove an object at that index, but if you pass an Integer object, the remove() function will delete the first occurrence of that object.
You are using primitive type to do your removal of element. You can convert it the Wrapper class and do it. Change the removeLane method as follows:
public void removeLane(Integer lane) {
if(lanes.contains(lane)){
lanes.remove(lane);
System.out.println("Lane successfully reserved.");
}
else{
System.out.println("Lane is already reserved.");
}
}
ArrayList Docs
E remove(int index)- Removes the element at the specified position in this list.
boolean remove(Object o) - Removes the first occurrence of the specified element from this list, if it is present.
As you have sent an int primitive type to method remove it has called remove(int index). Instead just send an Integer object and then it will call method remove(Object o) and it will work fine.
Working Code:
package stackoverflow;
import java.util.ArrayList;
import java.util.List;
public class Race {
private static final Race INSTANCE // store one instance
= new Race(); // (this is the singleton)
List<Integer> lanes = new ArrayList<>();
public static Race getInstance() { // callers can get to
return INSTANCE; // the instance
}
private Race() {
lanes.add(1);
lanes.add(2);
}
public void removeLane(int lane) {
if (lanes.contains(lane)) {
lanes.remove((Integer) lane);
System.out.println("Lane successfully reserved.");
} else {
System.out.println("Lane is already reserved.");
}
}
public static void main(String[] args) {
assignLane(1);
assignLane(1);
}
private static void assignLane(int lane) {
Race race = Race.getInstance();
race.removeLane(lane);
}
}
Related
We have to create a object of any class to use their funtionalities unless those are static functionalities. But why we dont need to create a ArrayList object to use its methods like add, contains etc..
ArrayList<Egg> myList = new ArrayList<Egg>();
myList.add(a);
According to my understanding, myList is just variable which holds ArrayList object's reference of type ArrayList class. So again how can we write following without passing object to myList.
ArrayList<Egg> myList;
myList.add(a);
Complete code:
import java.util.ArrayList;
public class DotCom {
private ArrayList<String> locationCells;
public void setLocationCells(ArrayList<String> loc)
{
locationCells = loc;
}
public String checkYourself(String userInput)
{
String result = "miss";
int index = locationCells.indexOf(userInput);
if (index >= 0) {
locationCells.remove(index);
if (locationCells.isEmpty()) {
result = "kill";
}
else
{
result = "hit";
}
}
return result;
}
//TODO: all the following code was added and should have been included in the book
private String name;
public void setName(String string) {
name = string;
}
}
PS
I am referring heads first java book.
The ArrayList reference is being set in the setter method:
public void setLocationCells(ArrayList<String> loc)
{
locationCells = loc;
}
If this method is not called, and the reference not set before trying to use the ArrayList, then the code will throw a NullPointerException.
Side note: This does not look to be safe code, since it can be easily run incorrectly and so a NPE is easy to create. Better perhaps to set the ArrayList (List is even better) in a constructor.
I got a class used in an Android app, which is declared like this:
public static class MyData implements Comparable<MyData>
{
public MyEnum myEnum;
#Override
public int compareTo(MyData another)
{
if(this.myEnum.equals(MyEnum.Value1))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value1))
{
return -1;
}
if(this.myEnum.equals(MyEnum.Value2))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value2))
{
return -1;
}
return 0;
}
}
I defined a list: List<MyData> myList = new LinkedList<MyData>();
After adding items to the list I call: Collections.sort(myList)
The problem is that when I debug, I see the compareTo method being called after the sort method is invoked, however it doesn't enter the first if even that it should. I even put the Boolean expression in Eclipse in the "Expressions" view and it returned true, but the code simply jumps to the return 0; and the list is not being sorted like I want to.
Why is that?
Eventually I changed that enum class member to an int member which was initialized with the ordinal value inside the Enum.
Then the compareTo method was changed like this:
#Override
public int compareTo(MyData another)
{
Integer myVal = this.intVal;
Integer otherVal = another.intVal;
return myVal.compareTo(otherVal);
}
I am trying to loop around the value that already got populated in Registration class. I have already put a breakpoint in getInstance() method in Registration class. When the cursor reaches the below for loop code.
for (final Registration.HolderEntry entry : Registration.getInstance()) {
// do other things..
}
I do a F5 on that. And then it gooes to getInstance() method of Registration class (below is the class). And when I inspect on instance variable at that point, I always see values populated in listOfBundles list which is good.
But if I keep on pressing F5 again, at some point it comes to iterator method in Registration class and then if I inspect on listOfBundles list, I don't see any values in that list which is what I am not able to understand why it is happening like this. No other code is running which might change the value of listOfBundles.
public class Registration implements Iterable<Registration.HolderEntry> {
private List<String> listOfBundles = new LinkedList<String>();
private final Map<String, HolderEntry> bundleMapper = new HashMap<String, HolderEntry>();
private Registration() {
//
}
private static class BundlesHolder {
static final Registration instance = new Registration();
}
public static Registration getInstance() {
return BundlesHolder.instance;
}
public synchronized void registerBundles(final String bundleName, final IBundleCollection collection) {
HolderEntry bundleHolder = new HolderEntry(bundleName, collection);
bundleMapper.put(bundleName, bundleHolder);
listOfBundles.add(bundleName);
}
#Override
public synchronized Iterator<HolderEntry> iterator() {
List<String> lst = new LinkedList<String>(listOfBundles);
List<HolderEntry> list = new LinkedList<HolderEntry>();
for (String clName : lst) {
if (bundleMapper.containsKey(clName)) {
list.add(bundleMapper.get(clName));
}
}
Collections.reverse(list);
return list.iterator();
}
// some other code
}
I hope the question is clear enough. Can anybody tell me what wrong I am going here?
because you use static instance always return same object from
public static Registration getInstance()
method. (only one time Registration is initialize).
there are no different object is your iteration. same object is iterating on your iteration. its not like applying to every object changes you make while iterate but it is same object you iterate and change values.
I dont know your real requirement. but try to use this.
public static Registration getInstance() {
return new Registration();;
}
I want to transfer a variable value of type List (variable name is seznamRacunov) from one class to another.
Class 1
public class UvoziRacun
{
private String potRacuna;
private List<String> seznamRacunov = new ArrayList();
public void setRacun(List<String> seznamRacunov)
{
this.seznamRacunov = seznamRacunov;
}
public List<String> getRacun()
{
return seznamRacunov;
}
public String getPotRacuna()
{
return potRacuna;
}
public void showDailog()
{
try
{
JFileChooser racun = new JFileChooser();
racun.setCurrentDirectory(new File(""));
racun.setFileFilter(new javax.swing.filechooser.FileFilter()
{
public boolean accept(File f)
{
return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
}
public String getDescription()
{
return "XML Datoteka";
}
});
//racun.setMultiSelectionEnabled(true);
int r = racun.showOpenDialog(new JFrame());
if (r == JFileChooser.APPROVE_OPTION)
{
potRacuna = racun.getSelectedFile().getPath();
seznamRacunov.add(potRacuna); //value is stored
}
//System.out.print("Racuni: " + seznamRacunov);
}
catch(Exception ex){}
}
}
Class 2
public class PrikaziRacune extends javax.swing.JFrame
{
UvoziRacun rac = new UvoziRacun();
public PrikaziRacune()
{
initComponents();
try
{
System.out.print(rac.getRacun()); // value is null, why?
//jLabel2.setText();
}
catch(Exception ex){}
}
Method seznamRacunov.add(potRacuna); store a value into seznamRacunov in Class 1, but the value of list does not pass in class 2 where I called getter. What is wrong?
Method seznamRacunov.add(potRacuna); store a value into seznamRacunov
in Class 1, but the value of list does not pass in class 2 where I
called getter.
Thats because, you are trying to get() your List without even calling the method - showDailog() which in turn invokes your add() method to populate list.
Make sure, you invoke this method - showDailog() to populate the list, before you actually fetch the List with get method
Or, it would be better, if you add a constructor to your class, which does the task of initializing your List. Then you can create an instance using that constructor and thus you won't have any problem.
PS: - You should always have at least a 0-arg constructor to initialize your fields, rather than letting compiler handle this task for you.
And one more thing, you should never, ever engulp your exception by having an empty catch block. Else there is no point in catching them. Add a printStackTrace() call instead.
public PrikaziRacune() {
initComponents();
try
{
rac.showDailog(); // Will populate the list
System.out.print(rac.getRacun()); // You can get the value here.
//jLabel2.setText();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
Also, check your ArrayList declaration in your first class. You are using generic type List on LHS, and a Raw type ArrayList on the RHS. Its something that you should avoid.
Have Generic type on both the sides: -
private List<String> seznamRacunov = new ArrayList<String>();
Is it possible to have multiple iterators in a single collection and have each keep track independently? This is assuming no deletes or inserts after the iterators were assigned.
Yes.
Sometimes it's really annoying that answers have to be 30 characters.
Yes, it is possible. That's one reason they are iterators, and not simply methods of the collection.
For example List iterators (defined in AbstractList) hold an int to the current index (for the iterator). If you create multiple iterators and call next() a different number of times, each of them will have its int cursor with a different value.
Yes and no. That depend of the implementation of the interface Iterable<T>.
Usually it should return new instance of a class that implement Iterable interface, the class AbstractList implements this like that:
public Iterator<E> iterator() {
return new Itr(); //Where Itr is an internal private class that implement Itrable<T>
}
If you are using standard Java classes You may expect that this is done this way.
Otherwise You can do a simple test by calling iterator() form the object and then run over first and after that second one, if they are depend the second should not produce any result. But this is very unlikely possible.
You could do something like this:
import java.util.ArrayList;
import java.util.Iterator;
public class Miterate {
abstract class IteratorCaster<E> implements Iterable<E>, Iterator<E> {
int mIteratorIndex = 0;
public boolean hasNext() {
return mStorage.size() > mIteratorIndex;
}
public void remove() {
}
public Iterator<E> iterator() {
return this;
}
}
class FloatCast extends IteratorCaster<Float> {
public Float next() {
Float tFloat = Float.parseFloat((String)mStorage.get(mIteratorIndex));
mIteratorIndex ++;
return tFloat;
}
}
class StringCast extends IteratorCaster<String> {
public String next() {
String tString = (String)mStorage.get(mIteratorIndex);
mIteratorIndex ++;
return tString;
}
}
class IntegerCast extends IteratorCaster<Integer> {
public Integer next() {
Integer tInteger = Integer.parseInt((String)mStorage.get(mIteratorIndex));
mIteratorIndex ++;
return tInteger;
}
}
ArrayList<Object> mStorage;
StringCast mSC;
IntegerCast mIC;
FloatCast mFC;
Miterate() {
mStorage = new ArrayList<Object>();
mSC = new StringCast();
mIC = new IntegerCast();
mFC = new FloatCast();
mStorage.add(new String("1"));
mStorage.add(new String("2"));
mStorage.add(new String("3"));
}
Iterable<String> getStringIterator() {
return mSC;
}
Iterable<Integer> getIntegerIterator() {
return mIC;
}
Iterable<Float> getFloatIterator() {
return mFC;
}
public static void main(String[] args) {
Miterate tMiterate = new Miterate();
for (String tString : tMiterate.getStringIterator()) {
System.out.println(tString);
}
for (Integer tInteger : tMiterate.getIntegerIterator()) {
System.out.println(tInteger);
}
for (Float tFloat : tMiterate.getFloatIterator()) {
System.out.println(tFloat);
}
}
}
With the concurrent collections you can have multiple iterators in different threads even if there inserts and deletes.