hello everyone.
i'm working on a piece of code which is driving me crazy these days...
this is a project for an exam, and it is about creating a synonims/opposites dictionary.
there have to be many different functions, but here i will focus only on the "updating" of a list of synonims, and that has to be done calling a method on an object "Term" that adds another Term to his synonims list.

what i was trying to do - since if Y is synonim of X, X should also be added to Y's synonims list - is to call a method on Term1 that adds Term2 to an ArrayList stored inside Term1, and at the same time, adding Term1 to Term2's list.
it is a bit complicated to read, but very easy from a logical standpoint. i'm gonna show you my code to be clearer.

this is the basic structure of a term (object "Termine"):

Code java:

publicclass Termine implementsSerializable{privateString lemma;// this is the term nameprivateString desc;// this is its descriptionprivate ArrayList<Termine> sinonimi =new ArrayList<Termine>();// this is the synonims listprivate ArrayList<Termine> contrari =new ArrayList<Termine>();// this is the sunonims liststaticfinallong serialVersionUID =0;}

so, when i want to "flag" one term as a synonim to another one, for later use with the program, i have to use a method on the second one that adds the first to its list, but that same method HAS TO add to the first's list the second term too, probably, recursively.
this is the method i'm using right now, it works only to the extent to add one term to another's list, for the second - more complex part - it does nothing:

Code java:

publicvoid addSin (Termine t){// aggiunge un Termine alla lista di sinonimithis.sinonimi.add(t);// works: "this" gets updated with a new term in the vector
ArrayList<Termine> listaSinT = t.getSin();// i use another method to copy inside a new vector ("listaSinT") the contents of the synonims of "t"for(int i =0; i < listaSinT.size(); i++){// i look through the elements of the vectorString nextLem = listaSinT.get(i).getLemma();// i use another method to obtain EACH term's name (a string, which is also a primary key, as the description above) if(!(nextLem.equals(this.getLemma()))){// if the string found is NOT equal to the name of the calling object ("this") do as follows
Termine newT =new Termine (this.getLemma(), this.getDesc(), this.getSin(), this.getCon());// create a new term identical to "this"
t.addSin(newT);// call this same method on "t" to add "this" to its list}elseSystem.out.println("\""+this.getLemma()+"\""+"è già nella lista di sinonimi di \""+ t.getLemma()+"\"");// send an error message};}

as i've already told you, the method adds Term2 to the list of Term1, but it doesnt go farthest from there, this is a piece of a main class to test:

Code java:

one =new Termine (name1,desc1);
two =new Termine (name2,desc2);
three =new Termine (name3,desc3);// these 3 terms are created with input from the user
one.addSin(three);// adds "three" to "one"'s synonim list
one.addCon(two);// adds "two" to "one"'s opposite listSystem.out.println(one.toString());System.out.println(two.toString());System.out.println(three.toString());

the last 3 lines are used to check the outcome, and it prompts a toString() of all the terms: "one" carries correctly "three" as synonim and "two" as opposite, but the other two are shown to have both their vectors empty.

what am i missing? i tried many different solutions, trying to make them more and more complex, then more and more simple, but nothing worked.
i'm a bit frustrated -__-'

i hope the code is readable enough, i tried to change colors but it doesn't let me do it inside the code windows :-/
any kind of help would be immensely appreciated.
thank you very much to anybody that will try and give their help.

see you next time, have a good one.

October 11th, 2013, 06:32 AM

GregBrannon

Re: adding elements on two mutual ArrayList's

I'm going to oversimplify, because I don't understand why it's so complicated, and I can't imagine how/why recursion would ever be involved.

Let's agree that term1 and term2 are synonyms. Both term1 and term2 are Term instances and Term instances all have an ArrayList instance variable, 'synonyms'. When one wants to *pair* Term instances as synonyms, the method might look something like:

The above is not the final answer, because it will result in an infinite loop, continuing to add to the other's list until a stack overflow occurs. To resolve the infinite loop, a check to avoid adding duplicates to a Term object's list of synonyms will have to be added.

Since I've oversimplified, let me know where I have gone too far because I didn't understand the problem.

October 11th, 2013, 06:48 AM

Stormbringer

Re: adding elements on two mutual ArrayList's

first of all, thank you very much for your support.
and thank you for letting me correct myself in adding the second "y" to "synonym" :P i was failing at that so much.

anyway, the code of the method does the 2 things you cited.
the first command is the same as my this.sinonimi.add(t) and the second one t.addSin (newT) where "newT" is basically a copy of "this" from which we are calling the method "addSin".

i've put the second inside an if-else command which is the control structure i've used: it checks if the "lemma" (stands for term name) of term2 is already present in the list of synonyms of term1, which i cycle through with the for.

point is it doesn't work. probably i'm fucking up the cycle or the conditional command. still can't get it.

p.s. how did you get the code so well formatted and colored?

October 11th, 2013, 07:12 AM

GregBrannon

Re: adding elements on two mutual ArrayList's

I suspect you'll have to write your own equals() method to ensure it returns the desired results. You're probably wholeheartedly excluding List objects rather than their contents when you check for duplicates.

As for code formatting in posts, the [ highlight=java] code here [ /highlight] tags (without the leading spaces) adds the extra stuff.

Edit: And no worries about the spelling. Your English is excellent.

October 11th, 2013, 07:24 AM

Stormbringer

Re: adding elements on two mutual ArrayList's

thanks for the hunches and infos about the spelling (and for your kindess too ;) )...

as for the code, i didn't get what was my mistake, as in "excluding List object...". do you mean i should work on the strings in the object in a different way?

But the contains() method uses the default equals() method - the one provided by the Object class - to compare existing elements of synonyms to term2 to determine if term2 is already present. Since synonyms elements are all Term objects, the result of the equals() method will always return true.

I don't think you're using the contains() method, but you're using the equals() method directly which will provide the same undesirable results. To improve the results, write your own Term.equals() method that provides an appropriate comparison. I don't know how Term is setup, but I imagine there is an instance variable for the actual word, like String term, so a possible equals() method to compare Term instances might be:

This equals() method is (again) oversimplified (and may be sufficient for your needs), but you can learn how to write a good Java equals() method by searching. There are several decent articles written on the topic.

October 11th, 2013, 01:19 PM

Stormbringer

Re: adding elements on two mutual ArrayList's

i think i get what you mean. the rationale behind my duplicate protection block was exactly this one, but seems that i have implemented it wrong, since your explaination sounds right, even if the equals() you wrote seems similar to my solution.
i will try it out right away and tell you about the results.
for now thanks for your help, i really appreciate it. a second pair of eyes (with a brain behind them) is REALLY useful in these matters.

--- Update ---

as Vic Mackey would say... "Not there yet."
turns out your idea was the same as mine, just moved into an independent method to call inside the one to add synonyms.

this is the situation, with your implementation.

this is the method to add a new synonym (addSin(Termine t)): the part in which the calling object (the term "this") is to be added to EACH SYNONYM in the list of the parameter object (the term "t").

Code java:

publicvoid addSin (Termine t){this.sinonimi.add(t);// adds term "t" to the list of synonyms (ArrayList "this.sinonimi") of the calling object ("this")
ArrayList<Termine> listaSinT = t.getSin();// i use method get.Sin() to store inside a variable a copy of the list of synonyms of "t"// HERE COMES THE IMPORTANT PARTfor(int i =0; i < listaSinT.size(); i++){/* "listaSinT" is a vector (ArrayList) that stores every synonym inside the object "t", the cycle goes through all its elements */if(this.checkDup(t))// this is the method to check for duplicates in a form similar to what you suggested (see below)
t.addSin(this);// this is the simple method to add a synonym, it's called by object "t" and gets "this" as a parameter}}

down here, i put the <handmade> equals() method you inspired:

Code java:

publicboolean checkDup (Termine t){if(this.lemma.equals(t.getLemma()))/* "lemma" is the plain name of the term, and it's a String. we compare it to "t"'s name using the method getLemma() to return it*/returntrue;// duplicate found: returns trueelsereturnfalse;// not found: returns false}

to clarify even more, i put right down here the istance variables of the objects we are handling all the time here, the class "Termine" (which is simply italian for "Term"). I'll copy just variables and not al the constructors and methods, i'll translate comments to make it understandable, but if you followed me 'till now, you already got basically all that these things mean.

Code java:

publicclass Termine implementsSerializable{privateString lemma;// this is the word itself, the name of the termprivateString desc;// this is the description of the termprivate ArrayList<Termine> sinonimi =new ArrayList<Termine>();// this is the vector (left empty as default condition) of all the synonyms of the termprivate ArrayList<Termine> contrari =new ArrayList<Termine>();// this is exactly identical to the list right above it, just that stores opposites instead of synonymsstaticfinallong serialVersionUID =0;// this is here just for the sake of binary save/load}

October 11th, 2013, 04:10 PM

GregBrannon

Re: adding elements on two mutual ArrayList's

One can only talk abstract design for so long. I put the following demo together as an example of what I'm thinking which has the elements of what I described above but applied slightly differently or in different places. I hope it helps.

Code java:

importjava.util.ArrayList;importjava.util.Arrays;importjava.util.List;// class MultpleListsDemo demonstrates how to manage adding the same item// to two lists which happen to be instances of the same objectpublicclass MultipleListsDemo
{// a list of contents which belong to both lists with duplicatesprivatefinalString[] addList ={"one", "two", "three", "four", "one",
"five", "six", "two", "seven", "eight", "nine", "ten"};// two Item instances that will contain the same items
Item item1;
Item item2;// default constructor creates the two Item instances in which// the similar items will be held and then runs the simple demopublic MultipleListsDemo(){
item1 =new Item("numbers");
item2 =new Item("numerals");// runs the demo
runDemo();}// method runDemo() adds the list of common terms to the first item,// adding them also to the second item without adding duplicates// to either one. adding the same list of terms is then added to the// second list to ensure duplicates will not be added to either Item// instanceprivatevoid runDemo(){System.out.println("Adding the terms to Item1 . . .");for(String itemToAdd : addList ){
item1.addTerm( itemToAdd, item2 );}System.out.println("\nAnd the results are:");// printing out the resulting contentsSystem.out.println("Item1 contains: "+ item1 );System.out.println("Item2 contains: "+ item2 );System.out.println();System.out.println("Adding the same terms to Item2 . . .");// try adding the list again to item2 (which will add to item1)for(String itemToAdd : addList ){
item2.addTerm( itemToAdd, item1 );}System.out.println("\nAnd the results are:");// printing out the resulting contentsSystem.out.println("Item1 contains: "+ item1 );System.out.println("Item2 contains: "+ item2 );}// the main method calls the demo class which initializes the necessary// variables and then presents the demopublicstaticvoid main(String[] args ){new MultipleListsDemo();}// end method main()}// end class MultipleListsDemo// how i imagine the Item class might look but without any frillsclass Item
{String itemName;
List<String> terms;// single-parameter constructor that gives the item a namepublic Item(String itemName ){this.itemName= itemName;
terms =new ItemList<String>();}// end constructor Item()// adds a term provided by the first parameter to this list and// then to the second list passed as the second parameter publicvoid addTerm(String itemToAdd, Item item2 ){// checks for duplicates and returns if foundif(!terms.contains( itemToAdd )){
terms.add( itemToAdd );}else{return;}// otherwise the item is added to the second list
item2.addTerm( itemToAdd, this);}// a toString() method that may be more complicated than it needs to be// but . . . publicString toString(){return terms.toString();}privatefinalclass ItemList<E>extends ArrayList<E>{
@Override
publicboolean contains(Object item2 ){for( E list1Item :this){if( list1Item.equals((E)item2 )){returntrue;}}returnfalse;}// end method equals()
@Override
publicString toString(){return(Arrays.toString(this.toArray()));}// end method toString()}// end class ItemList}// end class Item

October 12th, 2013, 05:00 AM

Stormbringer

Re: adding elements on two mutual ArrayList's

for starters, i really feel to thank you again because you are - actually - staying with me and trying your best to let me come through this one, and for that i must appreciate and reiterate how grateful i am.

as for seconds, i'm now going through your last code piece, to try and understand it well and launching it on my eclipse and see how it can actually help (for now im just about at the start trying to understand it and i thought to write this first).

i'll let you know what i come up with.

October 12th, 2013, 05:30 AM

GregBrannon

Re: adding elements on two mutual ArrayList's

You're welcome, and good luck. Let me know if you have any questions.

October 12th, 2013, 12:35 PM

Stormbringer

Re: adding elements on two mutual ArrayList's

i've bashed my head on this same fucking method for almost 5 hours today.
those were not straight because i managed to have a shower and eat lunch, but they were 1.5 hrs ---> brief return to life of a human being ---> 3+ hrs

you pointed me to the right direction and i think i got close to my goal, but it still doesn't work well: i'm testing vectors with just one element, so that hints that MAYBE my redundant commands are sometimes inserting/erasing the same thing over and over until SOMETIMES it stays, and SOMETIMES it gets deleted...
but anyway this has become my personal hell, lately...

i'll try and post something soon, but i feel im close: even if my code is unsecure - not being so messy - it has some logic in it and maybe i could come up with what im looking for. still im growing a bit more desperate by each passing moment...

the point is that i don't think it's very clever and polite to paste here all of my tries, i'd like it best to show you something that works, even if sloppy :-(

October 12th, 2013, 12:55 PM

GregBrannon

Re: adding elements on two mutual ArrayList's

Whenever you're ready. If posts were limited to elegant code that worked exactly as intended, there wouldn't be much point to the forum, but I understand your point.

I read a related blog post recently that I thought made a good point. The blogger was wishing he'd been more open, sharing and collaborative from his earliest days as a developer, "putting himself out there," so to speak. He learned the value of it as a more senior developer, and figured it had taken him a lot longer to get there than if he'd have been more open to learning from others by sharing his ideas with those who could have given constructive criticism and giving the same to those who needed it when he could.

October 12th, 2013, 01:23 PM

Stormbringer

Re: adding elements on two mutual ArrayList's

i'm adding something because reading again the conversation makes me think that maybe my poor explaination and the following confusion may have cast some misunderstanding on what i want my two (similar) methods to do.

i'll use some schematics instead of java:

Code :

class Term:
has a String "name".
has a String "description".
has a vector "synonyms" type Term:
that means he carries a collection of complex objects
(which have their own vectors).
has a vector "opposites" type Term:
that means he carries a collection of complex objects
(which have their own vectors).
method addSynonym:
it can be called by any Object type "Term", has to have another Object type "Term" as parameter,
which has to be added to the calling one.
method addOpposite:
it can be called by any Object type "Term", has to have another Object type "Term" as parameter,
which has to be added to the calling one.

what is ruining my life are the two methods, one is easier (synonyms) one is a bit harder (opposites), even if at start i thought them to be roughly the same, they aren't.
i've used very similar loops, with a duplicate check like yours, to do a series of 5 numbered procedures using the various fileds of each Term.
i'll explain what my code TRIES TO DO up until now, without delivering IN THE RIGHT WAY:

Code :

method addSynonym(Term t):
1) adds EACH Term in the SYNONYMS vector of the calling obj ("this"), to the SYNONYMS vector of "t" (see: if X == Y and Z == X, Z == Y)
2) adds EACH term in the OPPOSITES vector of the calling obj ("this"), to the OPPOSITES vector of "t" (same identical thing, different vector)
3) and 4) repeat but backwards (trying to get the best filtering from the if block), synonyms from "t" get imported inside the calling obj synonym vector; opposites of "t" to opposites of calling obj.
5) FINALLY Term "t" gets imported inside the calling object's synonyms vector.

the second method is not the same because it crosses the references:

Code :

method addOpposite(Term t):
1) adds EACH Term in the OPPOSITES vector of the calling obj ("this"), to the SYNONYMS vector of "t" (see: if X != Y and Z != X, Z == Y)
2) adds EACH term in the SYNONYMS vector of the calling obj ("this"), to the OPPOSITES vector of "t" (same identical thing, different vector)
3) and 4) repeat but backwards (trying to get the best filtering from the if block), opposites from "t" get imported inside the calling obj synonyms vector; synonyms of "t" to opposites of calling obj.
5) FINALLY Term "t" gets imported inside the calling object's opposites vector.

i've made 100 x2 lines of code that repeat the same construct with roughly (or every) combination, to get the job done. but the output of my testing main class its showing me i've failed. here's the output of my adding a single synonym(3) to a first term(1) and a single opposite(2) to the same term ("..." means an empty vector):

Code :

"good"
what is good
SYNONYMS:
right; right.
OPPOSITES:
bad.
"bad"
what is not good
SYNONYMS:
...
OPPOSITES:
right.
"right"
something that is not bad
SYNONYMS:
...
OPPOSITES:
...

--- Update ---

(i didnt read your last reply because i was compiling as precisely as i could my last post, but thinking it over: i'm really seeing now that blogger's point. but that's obvious now, since it has been 2 days we are chatting on this matter ^^)

--- Update ---

(deleting the double post)

October 12th, 2013, 01:38 PM

GregBrannon

Re: adding elements on two mutual ArrayList's

Yes, you've changed the problem. You've certainly made it more complex, at least in your approach to it, but I haven't thought about it enough to see why it has to be so much more complex. I'll stew on it while I relax away this day that isn't much good for anything else. (Sorry, that may be insensitive to your frustration.)

October 12th, 2013, 01:48 PM

Stormbringer

Re: adding elements on two mutual ArrayList's

sure, for today i've also broke myself on it enough for a day xD

here in italy it's 19:46, so since i didn't do anything else for now i'll rest too.

thanks for your invaluable help up until now. i hope to come up with this. due time approaches...

October 13th, 2013, 04:46 AM

GregBrannon

Re: adding elements on two mutual ArrayList's

I've read your last description of the problem several times, and I probably get lost along the way, but I don't see or don't understand the problem. It's time to give a short bit of code that demonstrates what you're trying to do with the problem clearly shown.

October 14th, 2013, 11:52 AM

Stormbringer

Re: adding elements on two mutual ArrayList's

okay. i paste here the exact method as it is in front of me now when i'm working on the code for the project. i put on top of it the istance variables and the constructor used in the method (which is the most overloaded).

so... this is it for now. no blinding flash of light with the gift of newfound wisdom, even if i hoped so :-( sometimes, i thought to have found the solution, but after a lot of time spent on understanding and then implementing, the behaviour remained faulty.
but for now the code is resting too similar to itself, because since 2 days ago i couldn't make it to change much of the key aspects, because had no new ideas :-/

anyway, i really hope that my code and my comments are understandable even if maybe too insecure and unskilled in your view (i know they are ^^').
but i spent a lot of time trying to present it and comment it in english in the best way possible, so that at least the understanding isnt frustrating.

thanks for your precious help up until now, because even if i still didn't resolve the matter i feel that you are pointing me to the right direction, inspiring me and correcting some of my logical messes, and thanks again for your good will and politeness ^^

"Input" is a class provided by the professor and used in all the course, it's for user's keyboard input.
"Dizionario" is another class in my project (which is a collection of Termine's).
i didn't finduseful to paste them too.

As I said in post #16, "It's time to give a short bit of code that demonstrates what you're trying to do with the problem clearly shown." This isn't a short bit, and it doesn't demonstrate anything, because I can't run it to get the results, errors, whatever it is that you've been tearing your hair out about. I can read the code to go to sleep each night, but I can't reliably see what it does or doesn't do without running it. The Java compiler in my biologic computer is limited to a few lines of simple code at a time, and even then it sometimes makes mistakes.

Sorry I can't be more help. I'll bet you figure it out eventually. Simplify where you can, breaking the complex parts into smaller, less complex - even easy - parts.

October 17th, 2013, 05:24 AM

Stormbringer

Re: adding elements on two mutual ArrayList's

sorry for the mess. i see what you are trying to tell me.
i'll work a bit on the project, then i'll try and put here a simplified version of the core method, maybe i'll reduce the number of vectors in each Term from 2 to 1 and get rid of other methods putting some variables public for the sake of showing.

another time around i thank you for your patience and your help. given that it's always very difficult to elaborate code written by someone else (and well written code too, while mine is clearly NOT), you have followed me up until now and gave me some very good advices, so i am really grateful because you already helped me a lot making me improve this code even if it still doesn't wor as intended.

--- Update ---

ok so here is something that's totally executable. first the rewritten and simplified class for terms.

Code java:

importjava.util.ArrayList;importjava.util.Collections;publicclass DemoTerm {/**Class DemoTerm
*
* A simplified version of class "Termine". It
* has variables set at "public" to enhance
* readability and reduce calling methods, each
* Term now doesn't have two vectors one for
* synonyms, one for opposites. it has one single
* vector TermList<DemoTerm> called "list"
* that is used alternatively for simulate the two.*/// INSTANCE VARIABLESpublicString name;publicString desc;public TermList<DemoTerm> list =new TermList<DemoTerm>();;// CONSTRUCTORSpublic DemoTerm(){};public DemoTerm (String n){this.name= n;}public DemoTerm (String n, String d){this.name= n;this.desc= d;}public DemoTerm (String n, String d, TermList<DemoTerm> l){this.name= n;this.desc= d;this.list= l;}// METHODSpublicvoid addSyn (DemoTerm t){for(int i =0; i <this.list.size(); i++){
DemoTerm tempTerm =this.list.get(i);if(!t.list.contains(tempTerm))
t.list.add(tempTerm);elsereturn;}// in this oversimplified method we add each Term in the list from// the parameter "t", to the list of the calling method "this"for(int i =0; i < t.list.size(); i++){
DemoTerm tempTerm = t.list.get(i);if(!this.list.contains(tempTerm))this.list.add(tempTerm);elsereturn;}// here we add each Term in the list from "this" to the list from "t"// in BOTH cases we run a duplicate check through the overwritten// contains() method provided by greg in the class TermList extends ArrayListthis.list.add(t);// in the final step we add "t" to the list inside "this"}publicString listToString(){// restituzione della lista dei sinonimi in formato stringaString s ="\r\n";Collections.sort(this.list, new DemoTermAlpha());for(int i =0; i <this.list.size(); i++){
s +=this.list.get(i).name;if(i ==(this.list.size()-1))
s +=".";else
s +="; ";};return s;}publicString toString(){String s ="\r\n";
s +="\""+this.name+"\"\r\n";
s +=this.desc+"\r\n\r\n";
s +="SYNONYMS or OPPOSITES:"+this.listToString();return s;}}

importjava.util.Comparator;publicclass DemoTermAlpha implements Comparator<DemoTerm>{/**TermAlpha is used to list alphabetically the Terms in the collection.*/publicint compare(DemoTerm t1, DemoTerm t2){if((t1.name.compareTo(t2.name))<0)return-1;elseif((t1.name.compareTo(t2.name))>0)return1;return0;}}

this is simple executable main class.
it creates 3 terms with user input. it adds term 2 to the list (of synonyms) of term one and then prints them all to screen to show the result. even simplifying the code the same errors remained. not compilation-wise, obviously. the same as before. term 1 gets term 3 in his list but term 3 doesn't show to have term 1 in its own.

Input 1st term name: blue
And its description: a cold color
Input 2nd term name: red
And its description: a warm color
Input 3rd term name: intense teal
And its description: actually its blue but got different name
"blue"
a cold color
SYNONYMS or OPPOSITES:
intense teal.
"red"
a warm color
SYNONYMS or OPPOSITES:
"intense teal"
actually its blue but got different name
SYNONYMS or OPPOSITES:

this is a BIG class, the Input class. don't bother looking at it, since i just use its "Input.readString()" method. is a basic keyboard input class provided by the professor (as already told you). just compile it with the rest. for my project i'd probably just need to copy one or two methods but for now i'm using it as it is.