Re: Algorithm for performing a rollup
Chris wrote:
This is a really basic question for an experienced programmer to ask,
but does anyone have a preferred algorithm for doing a rollup of items
in a list? I find myself writing ugly code over and over again to do this.
"writing ugly code over and over again" -- that's a /big/ mistake. Even if the
code were as beautiful as the day, it would still be a mistake that a halfway
decent programmer should not make.
It seems as if a utility method which creates a LinkedHashMap<X, Integer> would
do the trick quite nicely. Alternatively, if you don't want the expense of
creating an extra Collection, you could set up a little helper class as in the
attached code; with it you can say:
for (Group<String> g : Group.groups(args))
System.out.println(g);
where (in this example) "args" is a List<String> or String[] array.
Code follows. All sorts of elaborations are possible.
BTW, it looks a bit long, but it's really very short -- almost no real code,
just lots of Java-ish padding...
-- chris
=========== Group.java ===========
import java.util.*;
public class Group<X>
{
private final X m_value;
private final int m_count;
public // ctor
Group(X value, int count)
{
m_value = value;
m_count = count;
}
public X
getValue()
{
return m_value;
}
public int
getCount()
{
return m_count;
}
public String
toString()
{
return m_count + " * " + m_value;
}
public static <T>
GroupingIteratable<T>
groups(List<T> list)
{
return new GroupingIteratable<T>(list);
}
public static <T>
GroupingIteratable<T>
groups(T... elements)
{
return new GroupingIteratable<T>(elements);
}
}
======= GroupingIteratable.java =======
import java.util.*;
public class GroupingIteratable<T>
implements Iterable<Group<T>>
{
private final List<T> m_list;
public // ctor
GroupingIteratable(List<T> list)
{
m_list = list;
}
public // ctor
GroupingIteratable(T... elements)
{
this(Arrays.asList(elements));
}
public Iterator<Group<T>>
iterator()
{
return new GroupingIterator<T>(m_list.iterator());
}
}
======= GroupingIterator.java =======
import java.util.*;
public class GroupingIterator<T>
implements Iterator<Group<T>>
{
private final Iterator<T> m_iterator;
private boolean m_hasReadAhead;
private T m_readAhead;
public // ctor
GroupingIterator(Iterator<T> iterator)
{
m_iterator = iterator;
m_hasReadAhead = false;
}
public boolean
hasNext()
{
return m_hasReadAhead || m_iterator.hasNext();
}
public Group<T>
next()
{
T current = m_hasReadAhead
? m_readAhead
: m_iterator.next();
m_hasReadAhead = false;
m_readAhead = null;
int count = 1;
while (m_iterator.hasNext())
{
T next = m_iterator.next();
if (!current.equals(next))
{
m_readAhead = next;
m_hasReadAhead = true;
break;
}
count++;
}
return new Group<T>(current, count);
}
public void
remove()
{
throw new UnsupportedOperationException();
}
}
===============================