1

I have a class SimpleHistogram<DT> that takes in a generic array DT[] and I'm supposed to set the count, the number of times the element occurs in the array, of a specific item in the array to int count.

Here is what I have so far:

public class SimpleHistogram<DT> implements Histogram<DT>, Iterable<DT> {
    DT[] items;
    int size;

    public SimpleHistogram() {
    }

    public SimpleHistogram(DT[] items) {

        this.items = items;
    }
    @Override
    public void setCount(DT item, int count) {
        int n = 0;
        Iterator<DT> L = this.iterator();
        while (L.hasNext()) {
            DT dt = L.next();
            if (dt == item) {  // if dt equals to item, meaning item IS present, then
                n+=count;      // set the count of the item to count

            } else
            {this.add(dt, count)} // if its not equal, meaning its not there, then add the item and the count of the item
        }


    }
    private class Iterate implements Iterator<DT> {
        int index = 0;
        boolean lastRemoved = false;

        @Override
        public boolean hasNext() {
            return (index < items.length-1);
        }

        @Override
        public DT next() {
            if (index < (items.length) -1)
                throw new NoSuchElementException("No element at index");
            DT object = items[index];
            index++;
            lastRemoved = false;
            return object;
        }
    }

I'm struggling to implement the function setCount( DT item, int count) which is supposed to set the count of item to count.

Aditionally, if item does not exist already in the list, then we are supposed to add the item in and then set the count of the item to count.

I have provided explanations for what I intended to do but due to the fact that I am new to this, I haven't found sources that can properly clear this doubt, so any help would be greatly appreciated

Edit Here is the full code in case you may want to derive something from it. Test cases also presented below.

package histogram;

import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

// TODO: Uncomment this and make sure to implement all the methods

    public class SimpleHistogram<DT> implements Histogram<DT>, Iterable<DT> {
        DT[] items;
        int size;
    
        public SimpleHistogram() {
        }
    
    public SimpleHistogram(DT[] items) {

        this.items = items;
    }
    @Override
    public void setCount(DT item, int count) {
        int n = 0;
        Iterator<DT> L = this.iterator();
        while (L.hasNext()) {
            DT dt = L.next();
            if (dt == item) {  // if dt equals to item, meaning item IS present, then
                n+=count;      // set the count of the item to count

            } else
            {this.add(dt, count)} // if its not equal, meaning its not there, then add the item and the count of the item
        }


    }
    private class Iterate implements Iterator<DT> {
        int index = 0;
        boolean lastRemoved = false;

        @Override
        public boolean hasNext() {
            return (index < items.length-1);
        }

        @Override
        public DT next() {
            if (index < (items.length) -1)
                throw new NoSuchElementException("No element at index");
            DT object = items[index];
            index++;
            lastRemoved = false;
            return object;
        }
    }

    public int getCount(DT item) {
        int n = 0;
        Iterator<DT> L = this.iterator();
        while (L.hasNext()) {
            DT dt = L.next();
            if (dt == item) {
                n++;
            }

        }
        return n;
    }



    @Override
    public Iterator<DT> iterator() {

        return new Iterate();
    }

    @Override
    public int getTotalCount() {
        return items.length;
    }




}

Test cases:

public class SimpleHistogramTest {

    @Test
    public void testHistogram() {
        Character[] target = {'a','b','c','a'};
        Histogram<Character> h = new SimpleHistogram<>(target);
        Iterator<Character> iter = h.iterator();
        int elemCount = 0;
        while(iter.hasNext()) {
            iter.next();
            elemCount++;
        }

        assertEquals(3, elemCount);
        assertEquals(2, h.getCount('a'));
        assertEquals(1, h.getCount('b'));
        assertEquals(1, h.getCount('c'));
        assertEquals(4, h.getTotalCount());
    }
}
Droid
  • 520
  • 1
  • 7
  • I'm missing several things: what does "set the count of item" exactly mean for you? You wrote in your first sentence "the number of times the element occurs in the array", but do you mean you want to add that many elements into the array, or count how often the element appears there? The word "histogram" in the class name would lead me more to the "count how many" version, also the code does nothing to modify the contents of the array. Also why do you implement your own iterator and also the `Iterable` interface? – cyberbrain Oct 26 '22 at 15:59
  • I would expect the constructor to compute the histogram and store the results in a `Map
    `. Then `setCount()` would override the initial count for a given element. Are you confident all of the other stuff you have is required? I believe you are complicating the problem way more than needed.
    – erickson Oct 26 '22 at 16:02
  • @cyberbrain the "iterable" interface is used but in a different portion of the code which I'm already done with. and setting the count of the items mean take the current count of the item and modify it to the input count given in the function. If that means adding more items then sure – Droid Oct 26 '22 at 16:12
  • @erickson can you show me an easier way to do this? – Droid Oct 26 '22 at 16:13
  • @Droid the easier way is what erickson already described in their first comment. – Louis Wasserman Oct 26 '22 at 16:34

2 Answers2

0

Would something like this satisfy the requirements? It's essentially a wrapper around a map, where the elements are the keys, and each value is a count of that element. Presumably, the Histogram interface has additional operations like getCount(T); here, you'd just get the count from the encapsulated map.

class SimpleHistogram<T> implements Histogram<T>, Iterable<T> {

    private final Map<T, Integer> bins = new HashMap<>();

    SimpleHistogram() {
        this(List.of());
    }
    
    SimpleHistogram(List<? extends T> items) {
        for (T item : items) {
            Integer count = bins.getOrDefault(item, 0);
            bins.put(item, count + 1);
        }
    }

    @Override
    public void setCount(T item, int count) {
        bins.put(item, count);
    }

    @Override
    public Iterator<T> iterator() {
        return bins.keySet().iterator();
    }

}
erickson
  • 265,237
  • 58
  • 395
  • 493
  • is it possible to not use all of that collections stuff? Like it would be really helpful for me to just build on my existing code, or make as minimal changes as possible while implementing it, so that I can understand what's happening too – Droid Oct 26 '22 at 16:52
  • also using hashmap is really helpful, so if you could please use hashmap without all those collections stuff, it would be extremely useful for me – Droid Oct 26 '22 at 17:28
  • @Droid by "collections stuff", do you mean `Stream` stuff? Your own code was using `Iterator` and `Iterable` which is a core part of the Collections library. – erickson Oct 26 '22 at 18:30
  • yes I meant stream stuff. sorry for the misunderstanding, the Iterator is fine – Droid Oct 27 '22 at 03:28
  • @Droid Okay I replaced stream with a for-loop. – erickson Oct 27 '22 at 03:39
  • thank you, also one more thing, for setCount, if there the item does exist in the the array, and lets say the count of the item is 4, while the input int count is 6, does your setCount() method return 10, which is 4+6? – Droid Oct 27 '22 at 03:48
  • Also one more thing, your constructor doesn't work for my test cases, specifically, this one SimpleHistogram() { this(List.of()); }. – Droid Oct 27 '22 at 05:55
  • my test cases are provided at the end of the question – Droid Oct 27 '22 at 06:06
  • @Droid Yes, my example is meant to point you in the right direction, not to deprive you completely of your learning experience. If you have difficulty completing the small changes required, you can update your question or ask a new one, depending on how different the question is. But, in either case, you'll need to show what you've done and explain specifically where you are having difficulty. – erickson Oct 27 '22 at 18:07
-1

== compares the reference of an object in Java. equals() is also same.

If you want to compare two objects(dt and item) wit the same value, you need to override hashCode() and equals().

After that, you use equals() rather than ==.

Here is reference link.

Compare two objects with .equals() and == operator

changuk
  • 151
  • 4
  • 1
    I'm not sure what you mean by "`equals()` is also same." By default, yes, it tests identity, but the whole point is that it may be overridden by different types to do different things. As it stands, it's not clear that doing an identity comparison will cause any problems in this case. In other words, this is not an answer to this question. – erickson Oct 26 '22 at 16:04