More newbie questions

O

Ook

(newbie question thread consolidation thread)

Let me preface by saying I'm taking a java class, and my instructor likes to
see us maximize the usage of the collections framework whenever possible. He
wants an efficient oop design. I can get my code to run and do what I want,
but I'm not sure if I'm maximizing the usage of the collections framework,
and sometimes I make oop blunders. Hence my questions:

1) I have an ArrayList of Strings. I want to form a String that contains all
of the Strings, comma delimited. This is what I do. It works, but is there
are better or more correct way to do this?:

String returnValue = "";
for( String keyWord : _keywords )
returnValue = returnValue + keyWord + ", ";
// Strip off the last ", "
return returnValue.substring( 0, returnValue.length()-2 );


2) I have an ArrayList of Items, Item being a class with Strings and
ArrayLists or TreeSets of Strings. I need to search for and create a list of
items that have certain text in either the Strings, or the
ArrayList/TreeSets of Strings. I can do this, my code works, but again I'm
not sure I'm doing this most efficiently.

public class Item
{
private String _title1;
private String _title2;
private String _title3;
private TreeSet<String> list1 = new TreeSet<String>();
....
}

It was suggested I use a HashMap, but how would I implement that with the
above class, where I would have to search on different items in the class at
different times? My brute force code works, where I iterate through the list
with a for-each loop, checking each instance as I go through, but again may
not be the most efficient way.
 
B

Boaz.Jan

(newbie question thread consolidation thread)

Let me preface by saying I'm taking a java class, and my instructor likes to
see us maximize the usage of the collections framework whenever possible. He
wants an efficient oop design. I can get my code to run and do what I want,
but I'm not sure if I'm maximizing the usage of the collections framework,
and sometimes I make oop blunders. Hence my questions:

1) I have an ArrayList of Strings. I want to form a String that contains all
of the Strings, comma delimited. This is what I do. It works, but is there
are better or more correct way to do this?:

String returnValue = "";
for( String keyWord : _keywords )
returnValue = returnValue + keyWord + ", ";
// Strip off the last ", "
return returnValue.substring( 0, returnValue.length()-2 );

2) I have an ArrayList of Items, Item being a class with Strings and
ArrayLists or TreeSets of Strings. I need to search for and create a list of
items that have certain text in either the Strings, or the
ArrayList/TreeSets of Strings. I can do this, my code works, but again I'm
not sure I'm doing this most efficiently.

public class Item
{
private String _title1;
private String _title2;
private String _title3;
private TreeSet<String> list1 = new TreeSet<String>();
...

}

It was suggested I use a HashMap, but how would I implement that with the
above class, where I would have to search on different items in the class at
different times? My brute force code works, where I iterate through the list
with a for-each loop, checking each instance as I go through, but again may
not be the most efficient way.

instead of a
String returnValue = "";
use
StringBuffer returnValue = new StringBuffer();
and instead of doing
returnValue = returnValue + keyWord + ", ";
now you can use
returnValue.append(keyWord);
returnValue.append(", ");

more efficient then using Strings
at the return you can just to returnValue.toString();
 
B

Boaz.Jan

(newbie question thread consolidation thread)

Let me preface by saying I'm taking a java class, and my instructor likes to
see us maximize the usage of the collections framework whenever possible. He
wants an efficient oop design. I can get my code to run and do what I want,
but I'm not sure if I'm maximizing the usage of the collections framework,
and sometimes I make oop blunders. Hence my questions:

1) I have an ArrayList of Strings. I want to form a String that contains all
of the Strings, comma delimited. This is what I do. It works, but is there
are better or more correct way to do this?:

String returnValue = "";
for( String keyWord : _keywords )
returnValue = returnValue + keyWord + ", ";
// Strip off the last ", "
return returnValue.substring( 0, returnValue.length()-2 );

2) I have an ArrayList of Items, Item being a class with Strings and
ArrayLists or TreeSets of Strings. I need to search for and create a list of
items that have certain text in either the Strings, or the
ArrayList/TreeSets of Strings. I can do this, my code works, but again I'm
not sure I'm doing this most efficiently.

public class Item
{
private String _title1;
private String _title2;
private String _title3;
private TreeSet<String> list1 = new TreeSet<String>();
...

}

It was suggested I use a HashMap, but how would I implement that with the
above class, where I would have to search on different items in the class at
different times? My brute force code works, where I iterate through the list
with a for-each loop, checking each instance as I go through, but again may
not be the most efficient way.

sorry for spliiting the post..
iterating as you did is good enough.
if you get a ref to a String object (not a string value!!) and you
want to find in which item it is you can make a method that itrates in
all the Items and checks the
TreeSet.contains(Object 0) method
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeSet.html#contains(java.lang.Object)

a HashMap let you set you Key-Value pairs
you can set the String Value as your Key and set the String object
instance as your value
as so
key = "string to search" value = strSomeString
and then when you access the HashMap.get("string to search);
it will return you the strSomeString
how does it help you?
well its make your bruteforce iteration more efficient
instead of iterating the main collection and every sub-collection
within that collection
you only iterating the main collection and the sub-collection are now
being accessed with a constant time preformance - like an array

you should check the fine prints of the HashMap.get(Object o) method
about null values before ypu start implementing it
http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html#get(java.lang.Object)
 
M

Mark Jeffcoat

"Ook" <Ook Don't send me any freakin' spam at zootal dot com delete the Don't send me any freakin' spam> writes:

(You told us this was homework, and you actually wrote some
code. What an excellent beginning.)
1) I have an ArrayList of Strings. I want to form a String that contains all
of the Strings, comma delimited. This is what I do. It works, but is there
are better or more correct way to do this?:

String returnValue = "";
for( String keyWord : _keywords )
returnValue = returnValue + keyWord + ", ";
// Strip off the last ", "
return returnValue.substring( 0, returnValue.length()-2 );

I don't have any real problem with this, but I think
making returnValue a StringBuilder is a minor improvement.

If this were a very, very long list, I'd look for a way to
avoid that substring() at the end. I don't think that's worth
complicating the logic; your version is fine.

(For future reference: you could have written line 3 as
returnValue += keyWord + ", ";

But use StringBuilder instead.)
2) I have an ArrayList of Items, Item being a class with Strings and
ArrayLists or TreeSets of Strings. I need to search for and create a list of
items that have certain text in either the Strings, or the
ArrayList/TreeSets of Strings. I can do this, my code works, but again I'm
not sure I'm doing this most efficiently.

public class Item
{
private String _title1;
private String _title2;
private String _title3;
private TreeSet<String> list1 = new TreeSet<String>();
...
}

OOP aside: go ahead and get in the habit now of talking
about (and writing) designs in the most abstract way that
still expresses your intent. That is, in this example I'd
say you have a List of Items, instead of an ArrayList of
Items. In fact, unless order is important, you may well have
a Collection.

Consistently follow that rule, and not only will your methods
work on more kinds of things, but someone reading your code
will know that you used TreeSet there because you specifically
need a set that is ordered.

Oh; "TreeSet<String> list1" just can't be the best thing.
Sets and Lists are different kinds of Collections, and you
want to be very clear as to what you're talking about. (Unless
you don't care, because any kind of Collection will work.)
It was suggested I use a HashMap, but how would I implement that with the
above class, where I would have to search on different items in the class at
different times? My brute force code works, where I iterate through the list
with a for-each loop, checking each instance as I go through, but again may
not be the most efficient way.


If I understand you correctly, you want to write a
function that takes a Collection of Items, and returns
another Collection of Items that contains all the Items
that match a String. (With no restrictions at all on what
that String can be.)

My Item might have a static method like
public static Collection<Item> filter(Collection<Item> items,
String s) {

Collection<Item> passed = new ArrayList();
for (Item i : items) {
if (i.matches(s)) {
passed.add(i);
}
}
return passed;
}

That's probably pretty much the same as what you've got now.

I can't think of any way to use a Map that isn't silly.
If a Map's in the best answer, then either I've misunderstood
the problem, or I'm going to be very surprised by someone
else's answer.
 
N

Nigel Wade

"Ook" <Ook Don't send me any freakin' spam at zootal dot com delete the Don't
send said:
(newbie question thread consolidation thread)

Let me preface by saying I'm taking a java class, and my instructor likes to
see us maximize the usage of the collections framework whenever possible. He
wants an efficient oop design. I can get my code to run and do what I want,
but I'm not sure if I'm maximizing the usage of the collections framework,
and sometimes I make oop blunders. Hence my questions:

1) I have an ArrayList of Strings. I want to form a String that contains all
of the Strings, comma delimited. This is what I do. It works, but is there
are better or more correct way to do this?:

String returnValue = "";
for( String keyWord : _keywords )
returnValue = returnValue + keyWord + ", ";
// Strip off the last ", "
return returnValue.substring( 0, returnValue.length()-2 );

If you really want to maximize your use of the Collections framework then look
at AbstractCollection.toString()...
2) I have an ArrayList of Items, Item being a class with Strings and
ArrayLists or TreeSets of Strings. I need to search for and create a list of
items that have certain text in either the Strings, or the
ArrayList/TreeSets of Strings. I can do this, my code works, but again I'm
not sure I'm doing this most efficiently.

public class Item
{
private String _title1;
private String _title2;
private String _title3;
private TreeSet<String> list1 = new TreeSet<String>();
...
}

It was suggested I use a HashMap, but how would I implement that with the
above class, where I would have to search on different items in the class at
different times? My brute force code works, where I iterate through the list
with a for-each loop, checking each instance as I go through, but again may
not be the most efficient way.

Collections.binarySearch() perhaps?

http://java.sun.com/docs/books/tutorial/collections/algorithms/index.html
 
L

Lew

instead of a
String returnValue = "";
use
StringBuffer returnValue = new StringBuffer();
and instead of doing
returnValue = returnValue + keyWord + ", ";
now you can use
returnValue.append(keyWord);
returnValue.append(", ");

more efficient then using Strings
at the return you can just to returnValue.toString();

In addition to Boaz.Jan's advice, you might find it easier not to trim the
last comma, but to prevent it. (Underscore removed from the variable name in
order to conform to Sun-recommended conventions.) Also, StringBuilder is
recommended now instead of StringBuffer.

if ( keywords.size() == 0 )
{
return "'; // or null, as requirements specify
}
StringBuilder ret = new StringBuilder( keywords.get(0) );
for ( int ix = 1; ix < keywords.size(); ++ix )
{
ret.append( ", ").append( keywords.get(ix) );
}
return ret.toString();

Is your List guaranteed not to have null entries?

There is also a way to express the loop using an Iterator, which your
professor will no doubt like.

- Lew
 
L

Lew

a HashMap let you set you Key-Value pairs
you can set the String Value as your Key and set the String object
instance as your value
as so
key = "string to search" value = strSomeString

The "str" prefix is a bit counterproductive.

Map<String, String> map = new HashMap<String, String>;
....
map.put( someString, someString );

This is not so useful yet. (It is essentially equivalent to a HashSet, not
that that is relevant.) You need the string to look itself up.

I assume you are searching for any string in the data store that has the
search string as a substring? You didn't exactly say what the match criterion is.

public void init()
{
for ( String targetTerm : setOfAllPossibleTargetTerms )
{
for ( String searchTerm : setOfAllPossibleSearchTerms )
{
if ( targetTerm.indexOf( searchTerm ) >= 0 )
{
map.put( searchTerm, targetTerm );
}
}
}
}

public String search( String )
{
return map.get( searchTerm );
}

This can be quite an exercise if the universe of search and target terms is
large, and will fail utterly if the same search term could match more than one
target term.
and then when you access the HashMap.get("string to search);
it will return you the strSomeString
how does it help you?
well its make your bruteforce iteration more efficient
instead of iterating the main collection and every sub-collection
within that collection
you only iterating the main collection and the sub-collection are now
being accessed with a constant time preformance - like an array

you should check the fine prints of the HashMap.get(Object o) method
about null values before ypu start implementing it
http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html#get(java.lang.Object)

A better approach might be to google on "suffix tree".

- Lew
 
B

Boaz.Jan

The "str" prefix is a bit counterproductive.


that was to emphasis that it is an Object in the Value
oppsing to the Key which is a String Value
but never mind
the str prefix is irelevant
 
O

Ook

instead of a
String returnValue = "";
use
StringBuffer returnValue = new StringBuffer();
and instead of doing
returnValue = returnValue + keyWord + ", ";
now you can use
returnValue.append(keyWord);
returnValue.append(", ");

more efficient then using Strings
at the return you can just to returnValue.toString();

How about removing the final ", "? Is there a way, in the for-each loop, to
tell if we are on the last item in the list? In other languages I just strip
the trailing ", ", but this is a school assignment, and clever usage of the
collections framework impresses the instructor :p
 
L

Lars Enderin

Ook skrev:
How about removing the final ", "? Is there a way, in the for-each loop, to
tell if we are on the last item in the list? In other languages I just strip
the trailing ", ", but this is a school assignment, and clever usage of the
collections framework impresses the instructor :p
You could treat the first item specially, and add ", " before any
following item. Or have a boolean first, initialized to true, which is
used to decide if a ", " is needed.
 
D

Daniel Pitts

How about removing the final ", "? Is there a way, in the for-each loop, to
tell if we are on the last item in the list? In other languages I just strip
the trailing ", ", but this is a school assignment, and clever usage of the
collections framework impresses the instructor :p

StringBuilder returnValue = new StringBuilder();
for (String item: items) {
if (returnValue.size() != 0) {
returnValue.append(", ");
}
returnValue.append(item);
}

Or, instead of using for-each:

Iterator<String> iterator = items.iterator();
if (iterator.hasNext()) {
StringBuilder returnValue = new StringBuilder(iterator.next());
while (iterator.hasNext()) {
returnValue.append(", ").apend(iterator.next());
}
}
 
O

Oliver Wong

"Ook" <Ook Don't send me any freakin' spam at zootal dot com delete the
Don't send me any freakin' spam> wrote in message
How about removing the final ", "? Is there a way, in the for-each loop,
to tell if we are on the last item in the list? In other languages I just
strip the trailing ", ", but this is a school assignment, and clever usage
of the collections framework impresses the instructor :p

I can't think of an easy way to *not* add the ", " using a for-each
loop, and adding it, and later removing it, seems inelegant to me. So I'd
recommend using an explicit Iterator, e.g.

StringBuffer sb = new StringBuffer();
Iterator myIterator = myCollect.getIterator(); /*I forget the name of the
method to get the iterator, and too lazy to look it up right now*/
while (myIterator.hasNext()) {
Object whatever = myIterator.next()
sb.append(whatever.toString());
if (myIterator.hasNext()) {
sb.append(", ");
}
}

- Oliver
 
C

Chris Uppal

Oliver said:
StringBuffer sb = new StringBuffer();
Iterator myIterator = myCollect.getIterator(); /*I forget the name of the
method to get the iterator, and too lazy to look it up right now*/
while (myIterator.hasNext()) {
Object whatever = myIterator.next()
sb.append(whatever.toString());
if (myIterator.hasNext()) {
sb.append(", ");
}
}

I find that ugly -- the double call to hasNext() somehow makes the loop a lot
harder to understand than a simple boolean flag or Daniel's version using
returnValue.length().

Yet another way -- which is also ugly, but in some sense more direct than
anything shown so far:

StringBuilder returnValue = new StringBuilder();

.String separator = "";
for (String item: items)
{
returnValue
.append(separator)
.append(item);
separator := ", ";
}

"Look Ma, no conditionals !"...

-- chris
 
O

Oliver Wong

Daniel Pitts said:
StringBuilder returnValue = new StringBuilder();
for (String item: items) {
if (returnValue.size() != 0) {
returnValue.append(", ");
}
returnValue.append(item);
}

Nice! I had never thought of that.

- Oliver
 
C

Chris Uppal

Daniel Pitts wrote:

[me:]
Um, somebody has reverted to their pascal days. :)

Oops!

(Actually it's a carry-over from my day-to-day programming in Smalltalk, not
from some murky past as a Pascal user -- I have never used Pascal (yippee!). I
occasionally mistype self.someMethod() instead of this.someMethod() too ;-)

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top