Bypass max array size in no arg constructor - java

I am trying to remove the limit, through the default setting, when adding new numbers. I wish to still have a limit on the all-arg constructor, that is set when initialized, but not on the no-arg and 1-arg constructors.
public class SMSDataModelList implements SMSDataModelInterface, Serializable {
List<String> list = new ArrayList<String>();
//List<String> list = new LinkedList<String>();
private static final long serialVersionUID = 1L;
private static final int DEFAULT_MAX_NUM_PHONE_NUMBERS = 20;
public static final String FULL = "FULL";
public static final String DUPLICATE = "DUPLICATE";
private String message; //The SMS message
private String[] phoneNumbers; //The collection of phone numbers
private int maxNumPhoneNumbers; //Max numbers in list
public SMSDataModelList(String message) {
this(message, DEFAULT_MAX_NUM_PHONE_NUMBERS);
}
public SMSDataModelList() {
this("", DEFAULT_MAX_NUM_PHONE_NUMBERS);
}
public SMSDataModelList(String initialMessage, int maxNumPhoneNumbers) {
this.message = initialMessage;
this.maxNumPhoneNumbers = maxNumPhoneNumbers;
this.phoneNumbers = new String[maxNumPhoneNumbers];
}
#Override
public String addPhoneNumber(String newPhoneNumber) {
String result;
if (list.size() == maxNumPhoneNumbers) {
result = FULL;
} else {
boolean exists;
exists = findPhoneNumberIndex(newPhoneNumber) != -1;
if (exists) {
result = DUPLICATE;
} else {
list.add(newPhoneNumber);
result = newPhoneNumber;
}
}
return result;
}
}
I have tried adding this to the addPhoneNumber method:
if (DEFAULT_MAX_NUM_PHONE_NUMBERS == 20) {
maxNumPhoneNumbers = (list.size() + 1);
}
I thought this was working well with testing the no-arg and 1-arg constructors, but when it came to the all-arg, I noticed it allowed the array size to increase there too. I can see why that was wrong now, but not sure if I was on the right track.
Is it actually possible for me to make the no-arg and 1-arg constructors have unlimited array sizes with a static default?

If I understand what you mean, it seems you require another flag in your constructors, to indicate whether the number of phones should be limited to the initial maximum number:
public SMSDataModelList(String message) {
this(message, DEFAULT_MAX_NUM_PHONE_NUMBERS, false);
}
public SMSDataModelList() {
this("", DEFAULT_MAX_NUM_PHONE_NUMBERS, false);
}
public SMSDataModelList(String initialMessage, int maxNumPhoneNumbers) {
this(initialMessage, maxNumPhoneNumbers, true);
}
public SMSDataModelList(String initialMessage, int maxNumPhoneNumbers, boolean limited) {
this.message = initialMessage;
this.maxNumPhoneNumbers = maxNumPhoneNumbers;
this.phoneNumbers = new String[maxNumPhoneNumbers];
this.limited = limited;
}
You can use the limited flag to determine whether the phoneNumbers array can be increased when it becomes full - you'll need to add logic to addPhoneNumber that checks that flag.
P.S. I just noticed that your constructors and instance variables don't match the addPhoneNumber method. The constructors initialize an array to store the phone numbers while the addPhoneNumber method uses an ArrayList. You should decide which of the two you wish to use. An ArrayList would be easier, since you won't have to re-allocate a new array each time the existing array becomes full.

Related

Create tasks[] an array of task

My current problem is that I am assigned to created a program that should within the private fields assign tasks[] an array of task. Then within the constructor, that creates the task[] array, giving it the capacity of INITIAL_CAPAITY, and setting numTasks to zero.
I am new and confused on I can tackle this problem
I have tried declaring it within the constructor but there has been no luck.
Task.java
public class Task {
private String name;
private int priority;
private int estMinsToComplete;
public Task(String name, int priority, int estMinsToComplete) {
this.name=name;
this.priority=priority;
this.estMinsToComplete = estMinsToComplete;
}
public String getName() {
return name;
}
public int getPriority() {
return priority;
}
public int getEstMinsToComplete() {
return estMinsToComplete;
}
public void setName(String name) {
this.name = name;
}
public void setEstMinsToComplete(int newestMinsToComplete) {
this.estMinsToComplete = newestMinsToComplete;
}
public String toString() {
return name+","+priority+","+estMinsToComplete;
}
public void increasePriority(int amount) {
if(amount>0) {
this.priority+=amount;
}
}
public void decreasePriority(int amount) {
if (amount>priority) {
this.priority=0;
}
else {
this.priority-=amount;
}
}
}
HoneyDoList.java
public class HoneyDoList extends Task{
private String[] tasks;
//this issue to my knowledge is the line of code above this
private int numTasks;
private int INITIAL_CAPACITY = 5;
public HoneyDoList(String tasks, int numTasks, int INITIAL_CAPACITY,int estMinsToComplete, String name,int priority) {
super(name,priority,estMinsToComplete);
numTasks = 0;
tasks = new String[]{name,priority,estMinsToComplete};
//as well as here^^^^^^^^
}
My expected result is to be able to print out the list through honeydo class. I need to manipulate the code a bit more after adding a few other methods.
Your problem is that your constructor parameter tasks has the same name as that field of your class.
So you assign to the method parameter in your constructor, not to the field. And luckily those two different "tasks" entities have different types, otherwise you would not even notice that something is wrong.
Solution: use
this.tasks = new String...
within the body of the constructor!
And the real answer: you have to pay a lot attention to such subtle details. And by using different names for different things you avoid a whole class of issues!
Also note: it sounds a bit strange that a class named Task contains a list of tasks, which are then strings. The overall design is a bit weird...

Sort a list of Comparables using multiple string fields in a custom order

With this class:
public class MyClass implements Comparable<MyClass> {
private String status;
private String name;
private String firstName;
#Override
public int compareTo(MyClass o) {
return 0;
}
}
I'd like to sort a list of MyClass objects with this order:
Firstly, status = "open", then "working" then, "close"
Secondly, name = "toto", then "titi"
Finally, firstName = "tutu", "tata"
How can I do this with the Comparable interface ?
I would do this like so: first define a set of lists which define the order for each field:
private static List<String> statusOrder = Arrays.asList("open", "working", "close");
private static List<String> nameOrder = Arrays.asList("toto", "titi");
private static List<String> firstNameOrder = Arrays.asList("tutu", "tata");
Then use List.indexOf to get the position of the element in the list, and then simply subtract the results:
#Override
public int compareTo(MyClass o) {
final int statusComp = statusOrder.indexOf(status) - statusOrder.indexOf(o.status);
if (statusComp != 0) return statusComp;
final int nameComp = nameOrder.indexOf(name) - nameOrder.indexOf(o.name);
if (nameComp != 0) return nameComp;
return firstNameOrder.indexOf(firstName) - firstNameOrder.indexOf(o.firstName);
}
The issue with this approach is that indexOf will return -1 if the element is not in the list. You would need to define the behaviour in the case where MyClass contains non-standard values (perhaps it will never happen).

Java array list returning 0 value

I have created a class like this, which contains a bunch of arraylist as you can see. I've been setting the array with the methods add.. and then retrieving it with get.., when i tried to System.out.println numberofcitizen for example it is returning 0. Note that i have instantiated the class in another class to set the values.
public int numberOfCitizen;
private final ArrayList<Integer> citizenid = new ArrayList<>();
private final ArrayList<String> citizenName = new ArrayList<>();
private final ArrayList<Integer> citizenWaste = new ArrayList<>();
private final ArrayList<Float> longitude = new ArrayList<>();
private final ArrayList<Float> latitude = new ArrayList<>();
private final ArrayList<String> address = new ArrayList<>();
public void working() {
System.out.println("executing fine");
}
public void setnoOfcit(int number) {
this.numberOfCitizen = number;
}
public int getnumber() {
return this.numberOfCitizen;
}
public void addCitizenId(int citizen) {
citizenid.add(citizen);
}
public int getCitizenid(int i) {
int citId = citizenid.get(i);
return citId;
}
public void addCitizenName(String citizenname) {
citizenName.add(citizenname);
}
public String getCitizenName(int i) {
return citizenName.get(i);
}
public void addCitizenWaste(int waste) {
citizenWaste.add(waste);
}
public int getCitizenWaste(int i) {
return citizenWaste.get(i);
}
public void addLatitude(float lat) {
latitude.add(lat);
}
public float getLat(int i) {
return latitude.get(i);
}
public void addlng(float lng) {
longitude.add(lng);
}
public float getlng(int i) {
return longitude.get(i);
}
com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder vrpBuilder = com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder.newInstance();
public void runVPRSolver() {
System.out.println(numberOfCitizen);
System.out.println(getCitizenName(0));
//create a loop to fill parameters
Probable source of problem :
numberOfCitizen is a member attribute that you seem to never change. If you want it to represent the number of elements in your lists, either use citizenName.size() or increment the value of numberOfCitizen in one of the add methods.
Design flaw :
Your design takes for granted that your other class always use that one properly. Anytime you or someone uses that class, he must make sure that he add every single element manually. This adds code that could be grouped inside your class, which would be cleaner and easier to maintain.
So instead of several add method like this :
addCitizenid();
addCitizenName();
addCitizenWaste();
addLongitude();
addLatitude();
addAddress();
Design an other Citizen class which will contain those elements, and use a single list of instances of that class. That way you can use only one method :
private List<Citizen> citizenList = new ArrayList<>();
public void addCitizen(Citizen c) {
/*Add element in your list*/
citizenList.add(c);
}
This programming methodology is called "Encapsulation" which you can read about here
You need to increment numberOfCitizen in your add methods. For example:
public void addCitizenId(int citizen){
citizenid.add(citizen);
numberOfCitizen++;
}
I would also suggest encapsulating your variables into Objects, so create a citizen class:
public class Citizen {
private Integer id;
private Integer name;
private Integer waste;
}
And change your variable to an ArrayList of objects:
ArrayList<Citizen> citizens;

How would I input data into an array from user? I'm using accessors and mutators

Okay. Here's my first page with the accessors and mutators
public class TimeCard {
private int employeeNum;
private String[] clockInTimes = new String[14];
private String[] clockOutTimes = new String[14];
private float[] decimalClockIn = new float[14];
private float[] decimalClockOut = new float[14];
private float[] timeElapsed = new float[14];
public String[] getClockInTimes()
{
return clockInTimes;
}
public void setClockInTimes(String[] value)
{
clockInTimes = value;
}
}
My second class acessessing those set/get arrays.
How would I ask for user input for each array subscript 0-13?
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
TimeCard josue = new TimeCard();
System.out.println("Enter Monday Clock In Times:");
//not sure if this is right?
josue.setClockInTimes[0](reader.next());
}
}
By the way I need to do it like this because teacher wants it this way. I'm just not really sure how to get user input and put it into an array using an object class.
I'd probably start by changing your setter to take an index and a value, so something like this:
public void setClockInTime(int day, String clockInTime) {
this.clockInTimes[day] = clockInTime; // note you don't need to write "this," but it's clearer that this is a member field
}
And then in your main method:
for (int i=0;i<14;i++) {
String input = <get input>
josue.setCliockInTime(i, input);
}
Now you can set one value at a time, and that should let you populate all of your fields.

Webservice increment variable for id use singleton/synchronize

I am implementing a webservice witch is used to attack one DB.
i need to generate ID for objects that i store and i don't know what's the best way to do it.
i need to increment a INT.
Obviously the webservice must to be used for so much people and maybe various at same time.
so, what's is a good solution?
singleton/synchronize??
i think is the only way i know, maybe there are others better.
if u can show me one example it will be very appreciated.
thanks in advance!
Synchronize has horrible overhead. If all you need is an incremental counter, you can use AtomicLong's incrementAndGet(). Put the AtomicLong in a Singleton to have a server-wide access.
Edit: Some code example:
import java.util.concurrent.atomic.AtomicLong;
public class AtomicIdGenerator
{
private static class SingletonHolder
{
public static final AtomicIdGenerator instance = new AtomicIdGenerator();
}
public static AtomicIdGenerator getInstance()
{
return SingletonHolder.instance;
}
private AtomicLong mIdGenerator = null;
private AtomicIdGenerator()
{
mIdGenerator = new AtomicLong();
}
private AtomicLong getGenerator()
{
return mIdGenerator;
}
public long getNewId()
{
return getGenerator().incrementAndGet();
}
}
Usage example is simply:
long tNewId = AtomicIdGenerator.getInstance().getNewId();
This will be thread-safe, and without any overhead from synchronization. If you foresee yourself handling lots of concurrent use cases in the future, the java.util.concurrent package provides lots of battle-proven implementations for your use cases.
Use synchronize block to achieve this. In synchronized block only one thread can enter inside it.
JVM guarantees that Java synchronized code will only be executed by one thread at a time.
You can do something like this. I've done it a while back, it was based on PostgreSql and iBatis, but you can get the idea.
public class Sequence implements Serializable {
private static final long serialVersionUID = 7526471155622776147L;
private String name = null;
private int nextId = 0;
public Sequence () {
}
public Sequence (String name, int nextId) {
this.name = name;
this.nextId = nextId;
}
public final String getName () {
return name;
}
public final void setName (String name) {
this.name = name;
}
public final int getNextId () {
return nextId;
}
public final void setNextId (int nextId) {
this.nextId = nextId;
}
}
public class SequenceSqlMapDao extends SqlMapClientDaoSupport implements SequenceDao {
/**
* This is a generic sequence ID generator that is based on a database
* table called 'SEQUENCE', which contains two columns (NAME, NEXTID).
* <p/>
* This approach should work with any database.
*
* #param name The name of the sequence.
* #return The Next ID
* #
*/
public final synchronized int getNextId(String name) {
Sequence sequence = new Sequence(name, -1);
//Sequence sequence = new Sequence();
sequence = (Sequence) getSqlMapClientTemplate ().queryForObject("getSequence", sequence);
if (sequence == null) {
try {
throw new IllegalArgumentException("Error: SHOOT! A null sequence was returned from the database (could not get next " + name + " sequence).");
} catch (Exception ex) {
Logger.getLogger(SequenceSqlMapDao.class.getName()).log(Level.SEVERE, null, ex);
}
}
Object parameterObject = new Sequence(name, sequence.getNextId() + 1);
getSqlMapClientTemplate ().update("updateSequence", parameterObject);
int nextId = sequence.getNextId();
parameterObject = null;
sequence = null;
return nextId;
}
}
If nothing else this is pretty database agnostic. You'd still have to expose the method in your webservice.
PS - I forgot where I got this from, otherwise I'd give credit to proper source.

Categories

Resources