I'm writing a class that have a method of removing an object from other class. But it just worked inproperly, the output is not correct. Please help me through, and is there any better solution for this, I think my solution is quite cumbersome. Here is my code:
public List<Task> getTaskDue(){
List<Task> temp = this.taskCollection;
for (int unit = 0; unit < this.unitCollection.size(); unit++){
for (int j = 0; j < this.unitCollection.get(unit).getAssessmentCollection().size(); j++){
for (int i = 0; i < temp.size(); i++){
if (temp.get(i).getDueDate().compareTo(this.unitCollection.get(unit).getAssessmentCollection().get(j).getDueDate()) > 0)
temp.remove(i);
}
}
}
return temp;
}
Updated: I have Diary class that has list of Task class and Assessment class that hold due date attribute. I want to create a method that return a new list which have a list of over due task by comparing the task from diary class with the due date attribute from assessment class. The program compile successfully but the result is not correct if I want to test the list return no task item since no task is over due.
It seems like "removing" elements from the list isn't your ultimate problem.
You said you want your method to return a new list that contains elements from taskCollection based on some criteria. At the same time, I don't think you want to destroy or change taskCollection in any way.
So instead of creating temp as a reference to taskCollection, have it be a new ArrayList<Task>() instead. Then add tasks to temp (the new list) that you want to ultimately return from your method.
I am going to leave my adivce at that, because your code sample, in isolation, has a lot of unknowns that prohibit me from making any educated guesses on what you really need it to do.
Also, there are too many for loops! (I'm mostly kidding, but seriously...)
With more information from the comments below, I've modified your code to implement what I am suggesting. In order to add the items to temp (instead of remove them) I had to change your if statement from > 0 to <= 0. Also, instead of iterating over taskCollection in the inner-most loop, you should get tha tasks from the current assessment and iterate over those.
public List<Task> getTaskDue(){
List<Task> temp = new ArrayList<Task>();
for(int u = 0; u < unitCollection.size(); u++){
Unit unit = unitCollection.get(u);
for (int a = 0; a < unit.getAssessmentCollection().size(); a++){
AssessmentItem assessment = unit.getAssessmentCollection().get(a);
for (int t = 0; t < assessment.getTasks().size(); t++){
Task task = assessment.getTasks().get(t);
if (task.getDueDate().compareTo(assessment.getDueDate()) <= 0){
temp.add(task);
}
}
}
}
return temp;
}
If you need to alter a list as you're iterating through it, use a ListIterator. Call listIterator() on your list to create one, then see relevant methods on ListIterator.
You are removing an object from an index but index in iteration is not altered. Due to the reason you would be skipping an element in the list. Perhaps that is the reason why your results are not correct.
Change:
if ( temp.get( i ).getDueDate().compareTo( this.unitCollection.get( unit )
.getAssessmentCollection().get( j ).getDueDate() ) > 0 )
temp.remove(i);
to:
if ( temp.get( i ).getDueDate().compareTo( this.unitCollection.get( unit )
.getAssessmentCollection().get( j ).getDueDate() ) > 0 )
{
temp.remove(i);
i--;
}
PS: Better always practice using flower braces irrespective of number of statements under the condition or loop.
Related
I am trying to create a method which returns the place values of any two digits in a list that sum to zero. Where I am getting stuck is: creating the return method type, choosing the appropriate parameter to pass, and creating an empty list which holds the values to return.
Any help would be greatly appreciated!!
public class TwoSums {
public LinkedList<Integer> sum_values(LinkedList<Integer> input){
(Above) I am trying (but not sure how) to return a linked list from the method. I want the parameter to be a list with values like {3,-3,0,1}. I am also unsure of what the return type should be here.
int iterator = 0;
int scanner = 0;
LinkedList positions = new LinkedList<Integer>();
(Above) I am trying to create an empty list which I can push the place values of the parameter into, if they sum to zero
while(iterator<input.length){
if (iterator + scanner !=0){
scanner ++;}
else if (iterator + scanner ==0){
//push iterator and scanner values to the linkedlist
This is probably your homework, so I will just give you some guiding thoughts; I wont do the work for you!
First of all, the return type. Thing is: you can't just return single numbers. Because, you are interested in pairs of numbers. Thus you need some class like
public class IndexPair {
private final int firstIndex;
private final int secondIndex;
public IndexPair(int first, int second) { this.firstIndex = first ...
and then your method can simply return a List<IndexPair> object. Note: if you are serious here, you would want to override the equals method for example; in order to allow for easy comparison of IndexPair objects.
And of course: Java already knows some Pair classes which could be used here; instead of inventing your own thing.
The other problem: finding those pairs. A naive solution would be:
List<IndexPair> results = new ArrayList<>();
for (int firstIndex = 0; firstIndex < input.size(); firstIndex++) {
for (int secondIndex = firstIndex+1; secondIndex < input.size(); secondIndex++) {
if (input.get(firstIndex) + input.get(secondIndex) == 0) {
results.add(new IndexPair(firstIndex, secondIndex));
As said; the above is meant to get you going. There might be some typos or subtle bugs in that code. Take it as inspiration and work with it until it does what you need!
Edit: calling your method is as as
List<IndexPair> pairs = sum_values(Arrays.asList(-3, 3, 0, 0))
for example. But please understand: that is really basic stuff. Just do some reading around Lists and arrays. Those things have been documented many many times.
I am struggling with removing items from my arraylist. More specifically, I have two arraylists, being persons and vulcanos. Both are located in a grid. Each time step, people can move or not (this happens randomly, to the adjecant cells), while volcanos are static during the whole simulation. Volcanos can erupt or not. This is determined by a probability defined by the user. When at a certain timestep a person is located at the same cell as an erupting volcano, this person dies. But I don't know how I can remove that specific person from my array. So far I got the following (is repeated for each time step).
for (int j = 0; j < persons.size(); j++) {
for (int k = 0; k < volcanos.size(); k++) {
if ((persons.get(j).getXCoordPerson()) == (volcanos.get(k).getXCoordVolcano())
&& (persons.get(j).getYCoordPerson()) == (volcanos.get(k).getYCoordVolcano())
&& (volcanos.get(k).getEruptionStatus() == true)) {
// all persons being on the same cell as an erupting volcano die
}
}
}
You can do this with an Iterator too:
for(Iterator<Person> personIterator = persons.iterator(); i.hasNext(); ) {
Person person = personIterator.next();
for(Volcano volcano : volcanos) {
if(volcano.getEruptionStatus() &&
volcano.getYCoordVolcano() == person.getYCoordPerson() &&
volcano.getXCoordVolcano() == person.getXCoordPerson()) {
personIterator.remove();
}
}
}
In this case, you are using the iterator to do the removing, leaving the ArrayList in the state you want as a side effect of the loops.
One thing to watch out for is that you do not modify the list of people during this loop or you will end up with a ConcurrentModificationException. I'm assuming you have one single thread operating, and that this is for schoolwork or something similar. If you were doing this in the real-world, you would have to account for the fact that both lists (people and volcanos) could be changing at any time.
Try to mark your people as dead or harmed(etc.) or add them to another list. Then delete them after loop like
persons.removeAll(deadPeople);
If you don't mind working with Iterable instead of List, and if you don't mind taking dependency on Guava, then why not use Iterables?
Iterable<Person> filtered = Iterables.filter(persons, new Predicate<Person>() {
#Override
public boolean apply(Person person) {
for (Volcano v : volcanos) {
if (v.getEruptionStatus() &&
v.getXCoordVolcano() == person.getXCoordPerson() &&
v.getYCoordVolcano() == person.getYCoordPerson()) {
return false;
}
}
return true;
}
});
This will filter out all dead Persons, and will leave filtered with only living people
From what I know, object clone() creates a new copy of the cloned object. In my case I'm trying to clone the matrix of Symbol (which is a simple enum). this.table is the original object, while t is the clone. When I write a new value into a cell of t I would expect that this.table remains unchanged. However this is not the case and the second assert fails. (I added the first assert only to ensure the correctness of the second one).
Here is the code:
#Override
public State applyAction(Action action) {
int x = ((TickAction)action).x;
int y = ((TickAction)action).y;
Symbol[][] t = this.table.clone();
assert this.table[x][y] != currentPlayer.getSymbol();
t[x][y] = currentPlayer.getSymbol();
assert t[x][y] != this.table[x][y] ;
TableState ts = new TableState(t,this.currentPlayer.getNextPlayer());
ts.setLastAction(action);
return ts;
}
Note: with debugger I checked that t and this.table actually have different id, however after a second check I noticed that, despite this, their single cells have the same id. Then I'm much confused about this. Could someone explain me what's happening?
You have an array of arrays of Symbol instances.
When you call clone() on this.table, you get a new array, t, but each of the arrays in t is the same as the array in this.table.
In order to check that, you can try assert t[0] == this.table[0];.
In order to get a deeper clone, you would have to create a new array and initialize it yourself:
Symbol[][] t = new Symbol[][this.table.length];
for (int i = 0; i < t.length; i++)
{
t[i] = new Symbol[this.table[i].length];
for (int j = 0; j < t[i].length; j++)
{
// Here I am sharing the Symbol objects between the two arrays.
// If you do not want that, define your own way to copy or clone the object.
t[i][j] = this.table[i][j];
}
}
I'm just guessing here, but Java makes a distinction between == and .equals() and everyone gets burned once or twice using == with some object reference that actually needs .equal. Give this a try...
assert this.table[((TickAction)action).x][((TickAction)action).y].equals( currentPlayer.getSymbol() );
you cant use clone as is, it wont help you if you did not implemented it yourself.
same for equals(except strings)
I have a piece of code which involve a LinkedList. The followings
topic.read()
topic.delete() and
topic.send()
are methods from that LinkedList called Topic. These are being implemented in a GUI design. The methods
topic.read(name)
topic.send(text)
are working OK, but the
topic.delete(index)
is throwing me an
IndexOutOfBoundsException
I explain the methods briefly:read(name) and send(text) take String parameters and reads the topics and its list of messages and sends messages to topics receptively. The delete(index) should delete the index-specified message from the topic. However, the error message is telling me that the Size is 0.
The relevant piece:(I reckon that the piece should be enough, if needed more pieces will be added)
public void act(String s)
{
topic = new Topic(s, topics);
if (s.equals("Read"))
setEditorText(topic.read(readText()));
else if (s.equals("Delete"))
topic.delete(indexText());
else if (s.equals("Send"))
{
topic.send(getEditorText(), sendText());
clear();
}
}
Added these to this Quesion:
private JTextField indexText = new JTextField(10);
public int indexText()
{
return Integer.parseInt(indexText.getText());
}
public class Topic {
private LinkedList<String> messages = new LinkedList<String>();
public void delete(int index)
{
messages.remove(index - 1);
}
}
You need to do bounds checking then, if the index is valid, before deleting, such as:
if (index > 0 && index <= messages.size()) {
messages.remove(index - 1)
};
This will allow you to avoid IndexOutOfBoundsException
Hello Dilshat Abduwalli!
When you are getting a response that say your index size is 0 means that objects are not being added to the list or haven't yet been added and is why you go to delete said object of index value 2 for example it is going to throw an IndexOutOfBoundsException since the index is size is only 0. Ensure that you are adding values to your List or otherwise it will not be populated.
I would reccomend using #nitegazer2003 if statement you check for values that will fit within your List.size() you a integer isn't called that exceeds the List size which will give you the IndexOutOfBoundsException.
Double check your list values with a for loop.
for(int i = 0; i < list.size(); i++)
System.out.println(list.get(i)); //Print the Strings in the list (Assuming its a list of Strings)
Or
for(int i = 0; i < list.size(); i++)
System.out.println(list.getSize()); //Test the size of the list
Simular Question about Index 0 and OutOfBoundsException
The last posted response explains a similar answer. You don't have to read all his code though.
Oracle's List
Good source for documentation of List and its features.
I hope this helps or points you in the right direction! Good Luck!
I'm sure you probably get this a lot from CompSci students, I tried searching but mine looked a lot different from anything else I could find. Anyway, here is my class, it is supposed to sort an array of integers (then in the future be modified to sort objects, but ints will do for now).
My goal is to make an arrayList which is basically a row of buckets. then each bucket is a linked list. I feel like I'm on the right track, but the compiler doesn't like my last line of code, so I've run out of ideas.
here's an update. this is what I have now, but I still don't think it'll work
public void sorter(){
int highest_int = 0;
for(int i=0; i<entries.length; i++){
if (highest_int < entries[i])
highest_int = entries[i];
}
ArrayList<LinkedList<Integer>> row = new ArrayList<LinkedList<Integer>>();
LinkedList<Integer> column = new LinkedList<Integer>();
while (highest_int>0){
row.add(column);
highest_int--;
}
for(int i=0; i<entries.length; i++){
int j = entries[i];
column.add(0, j);
row.set(j, column);
}
}
The compiler "doesn't like" your code because the add() method of LinkedList doesn't return anything (has void return type). Therefore it cannot be used as an argument to the set() method. Basically, add() modified the object that it is called on, but doesn't return that object as a value.
The simplest change I can suggest that I think will make your code compile would be:
for(int i=0; i<entries.length; i++){
int j = entries[i];
column.add(0, j);
row.set(j, column);
}
Beyond that, it's not clear to me what you are actually trying to accomplish here. I don't see anything that looks like a sort at all.
The compile problem is that column.add() returns void.
A bigger problem is that the same LinkedList is used for each bucket. You need to create a new LinkedList in each iteration of one of the for loops.