I am currently developing a plugin in minecraft spigot. I don't believe this is a spigot problem though, I believe this is a java problem. I have a method called setInjury() in my class that is supposed to make a copy of a list, remove an item from the copy and replace the list with the new one. The weird thing is, this works. For one item in particular though, it just refuses to remove it. It will remove other ones, but not this one. I checked casing and everything. Even the boolean from .remove says it has been removed, yet it just doesn't.
(iStore is a file configuration file while store is my class it's in)
It used to be in an if else statement, but the boolean inside the remove works just the same. The weirdest thing about all of this is it was literally working yesterday.
List<String> sevs = iStore.getStringList(uuid + "." + section);
for(String s : iStore.getStringList(uuid + "." + section)) {
boolean isFracture = s.equals("Fracture") && injury.equals("Broken") ;
if(s.equals(injury)) {
continue;
}
sevs.add("Broken");
sevs.remove(isFracture ? "Fracture" : "Intact");
iStore.set(uuid + "." + section, sevs);
store.saveStore();
}
My other more messy code that does the same thing, to prove that it should remove it:
List<String> sevs = iStore.getStringList(uuid + "." + section);
for(String s : iStore.getStringList(uuid + "." + section)) {
if(sevs.contains(injury)) {
return;
}else if(injury.equals("Broken") && s.equals("Fracture")){
sevs.add("Broken");
sevs.remove("Fracture");
Bukkit.getLogger().info(Boolean.toString(sevs.remove("Fracture"))); //returns true??
iStore.set(uuid + "." + section, sevs);
store.saveStore();
}else{
sevs.add(injury);
sevs.remove("Intact");
iStore.set(uuid + "." + section, sevs);
store.saveStore();
}
List before running code:
rlegstat:
- Cured
- Fracture
//Desired result if injury is equal to broken:
rlegstat:
- Cured
- Broken
//Actual results
rlegstat:
- Cured
- Fracture
- Broken
Related
EDIT 2: Solved. Nothing special, just a wrong for-loop. Sorry.
This is my first question here. I am currently developing a GUI for easier creation of a config.xml for a certain importer software and I have basically written a data structure for XML with certain restrictions. Long story short, I tried to write a method as an alternative to toString which recursively prints all my data well-formatted. And well, as long as I don't get into the recursion everything goes just as planned. But as soon as I enable it...
This is the code:
private String details(boolean recursiveDetails, int tabs) {
if(recursiveDetails) System.out.println("DEBUG: launched details method with depth="+tabs);
String toStr = space(tabs)+"|============ <"+name+"> ============\n";
//recursion never reaches this point.
if(recursiveDetails) System.out.println("Debug check 1: before recursion with depth="+tabs);
int endlength = 28+name.length();
toStr += (space(tabs)+"| Parent: "+ parent +"\n");
if(contentString!=null && !contentString.equals(""))
toStr += (space(tabs)+"| Content String: \n| " + contentString+"\n");
toStr += (space(tabs)+"| Attributes: " + ((allAttr==null||allAttr.size()==0) ? "---" : "") + "\n");
for(Attribute a : allAttr)
toStr+=(space(tabs)+"| "+a+"\n");
toStr += (space(tabs)+"| Content: " + ((content==null || content.size()==0) ? "---" : "") + "\n");
//recursion!
for(Element e : content)
toStr+=(space(tabs)+"|" + (recursiveDetails ? e.details(true,tabs+1) : (" "+e)) + "\n");
if(recursiveDetails) System.out.println("Debug check 2: after recursion with depth="+tabs);
toStr += space(tabs)+"|";
for(int i=0; i<endlength; i++)
toStr+="=";
return toStr;
}
private String space(int tabs) {
String res="";
for(int i=0; i<tabs; tabs++)
res+=" ";
return res;
}
recursiveDetails is true when going for recursion, tabs is simply for indenting. content is a java.util.List of the same type as the class this method is in (Element), containing a variable amount of Element-objects. Every Element and Attribute object has a valid toString() method.
If I run the method with recursiveDetails = false on a small test structure, I get:
|============ <Catalog> ============
| Parent: <ImportConfig>
| Attributes:
| [Str | Project="null"]
| [Int | Priority="null"]
| Content:
| <Entry>
| <Entry>
|===================================
But once I run it with recursiveDetails = true I get this:
DEBUG: launched details method with depth=0
Debug check 1: before recursion with depth=0
DEBUG: launched details method with depth=1
Using breakpoints, I found out that everything works perfectly well, until the first line after the println. If I comment that line out, the program terminates at the next line and so forth. No Exceptions, no anything, no more printing.
I have tried using StringBuilder instead, replacing all + with .append(). I have also tried avoiding the a ? b : c operator, using classic ifs instead. The results are exactly the same.
Can anyone explain this to me?
EDIT: I am running Eclipse Java Neon on Ubuntu 16.04 Xenial with Java 8 OpenJDK amd64.
The loop in the spaces method is wrong. You have:
for(int i=0; i<tabs; tabs++)
and you almost certainly want to replace tabs++ with i++. Otherwise your loop will run indefinitely
The only possibility is that name is null and therefore name.length() throws a null pointer exception and your program dies.
Hey guys I have the following if condition...
//Add a space if necessary
if (i!=0 && spaceIn>0 && i%spaceIn==0) {
System.out.println("Converted Letter : " + curLtr + " at position " + i + " Needs a space");
curLtr = curLtr + " ";
};
The 1st 2 conditions are always true with the test input i give it.
Whats happening is the modula condition i%spaceIn==0 is not reporting as true when it is.
Example when i is 3 and spaceIn is 3 i%spaceIn=0 if condition works.
When i gets to 6 even tho i can see (from system.out further along) that the answer is 0 its not triggering the if condition.
Sometimes it wasn't doing it when i=12 either!
So weird.
Im printing out the answer to i%spaceIn throughout the loop and even tho the answer is 0 every multiple of 3 comes it sometimes wont trigger the if condition.
Same thing if spaceIn is 5. It skips 10. What ever number it is it seems to just skip sometimes for no reason.
What am i missing?
Use the following code...
You have terminated the if block... It can cause a problem...
if (i!=0 && spaceIn>0 && i%spaceIn==0) {
System.out.println("Converted Letter : " + curLtr + " at position " + i + " Needs a space");
curLtr = curLtr + " "; }
I hope it might work for you as it runs fine on my machine....
Following code written in Java
public static void main (String [] args) throws Exception
{
ordListe ol = new ordListe();
ol.lesBok("navn.text");
ol.leggTilOrd("hello");
ol.leggTilOrd("Hello");
Is my main method. This is about reading from file and adding to a arraylist(dictionary). ''Hello'' and "hello" is supposed to be the same word, and in the code under, it should increase the count of that word.
for (int i = 0; i < ordListe.size(); i++)
{
if (ordListe.toString().contains(s))
{
if (ordListe.get(i).toString().equalsIgnoreCase(s))
{
ord.oekAntall();
System.out.println("'" + s + "' That word is found and there are " + ord.hentAntall() + " of that word now in dictionary.");
break;
}
}
else
{
Ord ny = new Ord(s);
ordListe.add(ny);
System.out.println("'" + s + "' This word is added. " + ny.hentAntall() + " of this word in dictionary.");
break;
}
}
So this is a part of my code. From the main method I add words like ol.leggTilOrd("hello"); leggTilOrd is my method where the code right above is taken from. This is the part of the code that adds words to the dictionary/arrayList and checks if inputwords already exists. I have no problem with anything else than the specific if (ordListe.get(i).toString().equalsIgnoreCase(s)) part. If a word exist in the arrayList, I'm supposed to increase the count of that word. If not, I add the word in the arraylist (ordListe). The problem is that even if I add ol.leggTilOrd("hello") or ol.leggTilOrd("Hello"); with capital 'H', I can't get to recognize it as the same word even if I use the statements above. How do I do this, any other possibilites? This is my last possible effort, after many attempts earlier.
If there are anything questionable above, just tell me.
Change both strings to lower case before comparing and then comapare..it will help you and is easier!!! Use toLower function and then compare
The problem is this line:
if (ordListe.toString().contains(s))
Because 1) you do not compare the lowercase or uppercase versions of the two strings and 2) you probably not overrided toString so it returns the items in the list as you probably expect. Put this function in your ordListe class assuming that your ordliste extends arraylist:
public boolean containsIgnoreCase(String item) {
for(int i = 0; i < size(); i++) {
if (get(i).toString().equalsIgnoreCase(item)) {
return true;
}
}
return false;
}
Now you can call containsIgnoreCase to determinate if there is a specific item in the list ignoring the case
My code for deleting a player of a doubly linked list works right, but the System.out.print statements don't.
I placed System.outs.print statements before the removeFirst and removeLast because I don't know of a way to output the data that was removed in the nodes so I print it out before I remove.
I know my current method is bad design but I'm unsure of what function to use.
What conditions do I check for in an if-statement to see if the node has removed successfully?
else if (mChoice.startsWith("4")) {
System.out.println("What do you want to delete?");
mChoice = in.nextLine();
if (mChoice.contains("first")) {
System.out.println("Removed first player " + rBook.mHead.getData());
rBook.removeFirst();
}
else if (mChoice.contains("last")) {
System.out.println("Removed last player " + rBook.mHead.mPrev.getData());
rBook.removeLast();
}
else {
rBook.remove(rBook.searchByName(mChoice));
// System.out.println(rBook.get() + " removed."); this line
}
If you dont want to change your Player class and its functions try this:
else if (mChoice.startsWith("4")) {
System.out.println("What do you want to delete?");
mChoice = in.nextLine();
Player deleted;
if (mChoice.contains("first")) {
deleted = rBook.mHead.getData();
rBook.removeFirst();
System.out.println("Removed first player " + deleted);
}
else if (mChoice.contains("last")) {
deleted = rBook.mHead.mPrev.getData();
rBook.removeLast();
System.out.println("Removed last player " + deleted );
}
else {
deleted = rBook.searchByName(mChoice);
rBook.remove(searchByName(mChoice));
System.out.println(deleted + " removed.");
}
I would suggest that you modify your remove() function to return the element you just removed. So the code you're looking at would look like:
Player deleted = rBook.remove(rBook.searchByName(mChoice));
System.out.println(deleted.get() + " removed.");
If you want to store which elements of the list have been removed (to print or undelete them later, for example), then a better design would be either
only flagging these elements as removed, or
moving them into another, "history" list.
Which of these solutions is better depends on the problems you want to solve.
Sometimes, due to faulty data collected, a line generated by the following method ends up looking like this when saved: ",-1,0" or something similar, with no name, an ID of -1 and a level of 115 or something else. (The lines are formatted like this (excluding quotes): "name,id,level" (e.g: "Honour guard,5514,115")
What i need to do is to remove all strings in monstersToAdd that contains -1.
I've tried this, but with no success:
private void combineInfo() {
for(int i = 0; i < monsterList.size(); i++){
monstersToAdd.add("" + names[i] + "," + IDs[i] + "," + levels[i]);
}
monstersToAdd.remove(monstersToAdd.contains("-1"));
}
with the line monstersToAdd.remove(monstersToAdd.contains("-1")); I was trying to remove all strings in monstersToAdd that contains "-1". This however does not work, probably for good reasons, which I unfortunately don't know of yet.
I would really appreciate any input :).
You would be better off not adding the lines you don't want in the first place.
for (....) {
if (IDs[i] != -1) {
// add it
}
// else it simply doesn't get added
}
More on your original code: You could post a little more detail, such as the type of monsterToAdd. If it is a non-generic list, then the contains method just returns true or false depending if the parameter (here a string of "-1") is present in the list exactly as you pass it, that is it doesn't search for substring matches of the list elements.
remove then tries to remove the element you ask to remove, which may be a Boolean object, automatically boxed from the boolean primitive value returned by contains.
Also, it is suspicious that you have a variable called monsterList which you use for iteration length, but not actually use any elements from that list. Maybe the arrays you use have the same values as the list, and were copied out beforehand? If so, it would be nicer to iterate on the monsterList directly and use its elements.
Its easier if you dont even add them, than adding and removing them so check the sanity of ID names and levels before adding them
private void combineInfo() {
for(int i = 0; i < monsterList.size(); i++){
//add only if name is non empty, ID is not negative and level is below 100
if(!(names[i].isEmpty() || IDs[i]<0 || levels[i]>100))
monstersToAdd.add("" + names[i] + "," + IDs[i] + "," + levels[i]);
}
Why don't you do this instead:
private void combineInfo() {
for(int i = 0; i < monsterList.size(); i++){
if(IDs[i] != -1){
monstersToAdd.add("" + names[i] + "," + IDs[i] + "," + levels[i]);
}
}
monstersToAdd.remove(monstersToAdd.contains("-1"));
}
That way, you never add the monster to the list in the first place, if the ID is -1.
You are really close:
private void combineInfo() {
for(int i = 0; i < monsterList.size(); i++){
if (IDs[i] == -1) continue; // Skip this iteration
monstersToAdd.add("" + names[i] + "," + IDs[i] + "," + levels[i]);
}
}
Filter them out as early as possible rather than back-tracking and removing them.
contains() returns only a true/false result depending on whether the list contains the given input object (in your case the string "-1"). So in your example, your list wouldn't contain "-1", so your remove statement would be resolved to this:
monstersToAdd.remove(false);
which wouldn't work for obvious reasons.
Here is the code:
for(Iterator<String> it = monsterList; it.hasNext();) {
String elem = it.next();
if (elem.contains("-1")) {
it.remove();
}
}
contains() method of collection returns true if collection contains element equals to one passed as an argument. In you case you want to use String's contains() that returns true if the string contains specified substring. This is the reason that you need loop.
This loop must be implemented with iterator. Using new java 5 syntax for(String elem : list) will not work here because you have to remove element. Using for(int i = 0; i < list.size(); i++) requires implementation of logic that safely moves to the next index after element removal.
And the last point. You have to use iterator.remove() instead of Collection.remove() to avoid ConcurrentModificationException