Union of two object bags in Java - java

I need help with a Java homework problem. I have two bags, say bag1 containing the strings A, B, C and D and bag2 containing strings E, F, G and H. I need to write a BagInterface for the union of those two bag then a class call ArrayBag<T> implements BagInterface<T>.
BagInterface I was thinking something like this:
public interface BagInterface<T> {
public T union(T[] item);
}
public class ArrayBag<T> implements BagInterface<T> {
private final static int DEFAULT_CAP = 4;
private int numElements;
private T[] bag;
public ArrayBagR(int cap) {
bag = (T[]) new Object[cap];
this.numElements = 0;
}
public T union(T[] item) {
// Not sure how I should write this so I can pass
// another class object in the parameter
// Like say if I write a main to run this I could
// do something like Bag1.union(Bag2)
// and get something like A B C D E F G H
}
}
Like say if I have this
public static void main(String[] args) {
BagInterface bag1 = new ArrayBag(n);
BagInterface bag2 = new ArrayBag(m);
BagInterface<String> everything = bag1.union(bag2);
}

Per your example,
BagInterface bag1 = new ArrayBag(n);
BagInterface bag2 = new ArrayBag(m);
BagInterface<T> everything = bag1.union(bag2);
When you call, union on bag1 passing bag2 as argument,
this.bag -> represents bag1
item in the argument represent bag2
Now you can write something line. No need to return from this method. bag1 will be updated with union.
public BagInterface<T> union(T[] item) {
T[] everything = thi.bag;
for(T elem: item){
if(not(this.bag contains elem )){
everything -> add(elem);
}
}
return this;
}
Please note: This is a pseudo code to share the concept (not a code).
A sample java code can be like below:
public BagInterface<T> union(T[] item) {
List<T> unionList = Arrays.asList(this.bag);
for(T elem: item){
boolean present = false;
for(T elem1: this.bag){
if(elem1.equals(elem)){
present = true;
}
}
if(!present){
unionList.add(elem);
}
}
this.bag = unionList.toArray(new Bag[unionList.size()]);
return this;
}
Also you can further use List method contains to simplify the code as :
public BagInterface<T> union(T[] item) {
List<T> unionList = Arrays.asList(this.bag);
for(T elem: item){
if(!unionList.contains(elem)){
unionList.add(elem);
}
}
this.bag = unionList.toArray(new Bag[unionList.size()]);
return this;
}
If you don't want to update bag1 contents, you should have method like this:
public BagInterface<T> union(T[] item2) {
BigInterface<T> everything = new BagArray<T>();
List<T> unionList = Arrays.asList(this.bag);
for(T elem: item){
if(!unionList.contains(elem)){
unionList.add(elem);
}
}
everything.setBags(unionList.toArray(new Bag[unionList.size()]));
return everything;
}

Related

Java Implementation of T first() method to class Hashset<T>

I am having difficulty with the following exercise. I do not know which way to approach it. I know I should use some sort of iteration but I am unsure. I have been able to implement the T first() method with a binary search tree but not with a HashSet.
Add the following method to class HashSet<T> and write a suitable test program.
T first()
// least value in the set (if the set is empty
// throws NoSuchElementException)
import java.util.*;
import java.lang.Iterable;
class HashSet<T extends Comparable<T>> implements Iterable<T> {
private LinkedSet<T>[] hashTable; // hash table
HashSet() { // create the empty set
hashTable = (LinkedSet<T>[])(new LinkedSet[1000]);
// note coding trick!
for (int i=0; i<hashTable.length; i++)
hashTable[i] = new LinkedSet<T>();
//Exercise 1
int numItems = 0;
for (LinkedSet<T> miniSet: hashTable)
numItems = numItems+miniSet.size();
}
private int hash(T t) { // hash t into hashTable index
return Math.abs(t.hashCode()%hashTable.length);
}
int size() {
int numItems = 0;
for (LinkedSet<T> miniSet: hashTable)
numItems = numItems+miniSet.size();
return numItems;
}
boolean contains(T t) {
return hashTable[hash(t)].contains(t);
}
boolean add(T t) {
return hashTable[hash(t)].add(t);
}
boolean remove(T t) {
return hashTable[hash(t)].remove(t);
}
//Exercise 3
public Iterator<T> iterator() {
ArrayList<T> items = new ArrayList<T>();
for (LinkedSet<T> ls: hashTable)
for (T t: ls) items.add(t);
return items.iterator();
}
boolean addAll(HashSet<T> ts){
boolean changed = false;
for(T i : ts)
if(add(i))
changed =true;
return true;
// add all elements of ts to set; ts is unchanged.
}
}
import java.util.Iterator;
public class Prog {
public static <T extends Comparable<T>> T first(HashSet<T> hs)
// least value in the set (if the set is empty
// throws NoSuchElementException
{
T least = null;
for(T i : hs){
if (i.compareTo(least)<0){
i = least;
}
}
return least;
}
import java.util.List;
public class main1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<String> test1 = new HashSet<String>();
test1.add("sean");
test1.add("adam");
test1.add("ava");
HashSet<Integer> test2 = new HashSet<Integer>();
test2.add(2);
test2.add(10);
test2.add(5);
System.out.println(test1.size());
System.out.println(Prog.first(test2));
}
}
You can:
iterate through values: try for ( T x: the_set) ...
take the min: take the first, an iterate, and if new is less, take it
return that value (or exception if no value)
try to complete this
public static <T> T first(HashSet<T> _ht)
{
// if _ht empty throws an exception
// TODO
// Take the first (or any element)
// TODO
T least;
for (T one_element: _ht)
{
// compare one_element and least
// TODO
// and keep the least !
}
return least;
}
I agree with the comment from Peter, a HashSet has no concept of "first" or "last", since it's not ordered. However, there is the class TreeSet, which implements SortedSet.
The element type must define a natural order (e.g. int, or Comparable<T>), or otherwise you have to provide a Comparator<T> to the constructor of the tree set.
Example:
Integer[] numbers = { 5, 9, 1, 11 };
TreeSet<Integer> set = new TreeSet<>(Arrays.asList(numbers));
Integer least = set.first(); // 1
One possible implementation of the first() method (assuming a binary tree):
public T first() {
Node<T> p = root;
if (p != null) {
while (p.left != null) { // not "while (p != null)"
p = p.left;
}
}
return p == null ? null : p.item;
}

Methods with Different Signatures that Return the Intersection of Two Sets (Java)

I created a method that returns the intersection of two sets of values. The thing is that I want to use a different signature that uses only one arrayList within the method and not all of them.
public class Group <T>
{
ArrayList<T> w = new ArrayList<T>();
//Here I have the add and remove methods and a method that returns
//false if the item is not in the set and true if it is in the set
public static ArrayList intersection(Group A, Group B)
{
ArrayList list = new ArrayList();
ArrayList first = (ArrayList) A.w.clone();
ArrayList second = (ArrayList) B.w.clone();
for (int i = 0; i < A.w.size(); i++)
{
if (second.contains(A.w.get(i)))
{
list.add(A.w.get(i));
second.remove(A.w.get(i));
first.remove(A.w.get(i));
}
}
return list;
}
}
This is the other method with the different signature. How can I make this method to return the intersection of two sets if the signature is different from the method shown above?
public class Group <T>
{
ArrayList<T> w = new ArrayList<T>();
public static <T> Group<T> intersection(Group <T> A, Group <T> B)
{
Group<T> k= new Group<T>();
return k;
}
}
public class Main
{
public static void main(String [] args)
{
Group<Integer> a1 = new Group<Integer>();
Group<Integer> b1 = new Group<Integer>();
Group<Integer> a1b1 = new Group<Integer>();
//Here I have more codes for input/output
}
}
You cannot overload methods by their return value in Java - you'll have to rename one of them. E.g:
public static <T> Group<T> intersectionGroup(Group <T> A, Group <T> B)
public static ArrayList intersectionArrayList(Group A, Group B)

Sorting String differently on some conditional

I wondered how I could change ordering-direction only on some contitional. In my case Strings starting with 'BB' should be ordered in the other direction, everything else should be ordered as usual.
My Test-Class:
public class StringTest {
public static void main(String[] args) {
SomeClass someClass1= new SomeClass("AA");
SomeClass someClass2= new SomeClass("AB");
SomeClass someClass3= new SomeClass("CB4");
SomeClass someClass4= new SomeClass("BB7");
SomeClass someClass5= new SomeClass("BB9");
SomeClass someClass6= new SomeClass("BB3");
SomeClass someClass7= new SomeClass("CB3");
List<SomeClass> list = new ArrayList<SomeClass>();
list.add(someClass1);
list.add(someClass2);
list.add(someClass3);
list.add(someClass4);
list.add(someClass5);
list.add(someClass6);
list.add(someClass7);
Collections.sort(list);
for (SomeClass someClass : list) {
System.out.println(someClass.getSomeField());
}
}
}
My Comparator:
public class SomeClass implements Comparable<SomeClass>
{
private String someField;
public int compareTo(final SomeClass o)
{
int res = 0;
if (someField.startsWith("BB"))
{
res = o.someField.compareTo(someField);
}
else
{
res = someField.compareTo(o.someField);
}
return res;
}
}
My desired output:
AA
AB
BB9
BB7
BB3
CB3
CB4
The actual result so far:
AA
AB
CB3
BB9
BB7
BB3
CB4
Jonny
You need to make sure your Comparator applies the different sorting only when both elements start with "BB". Right now your Comparator applies the different sorting even if you compare "BB9" with "CB3" and therefore the latter is being sorted in front of BB9.
public class SomeClass implements Comparable<SomeClass>
{
private String someField;
public int compareTo(final SomeClass o)
{
int res = 0;
if (someField.startsWith("BB") && o.someField.startsWith("BB"))
{
res = o.someField.compareTo(someField);
}
else
{
res = someField.compareTo(o.someField);
}
return res;
}
}
if(someField.startsWith("BB") && o.someField.startsWith("BB")))
Try this change in your compareTo method which may solve your problem.

collections in java

So I have this code. Basically it should be able to take a stock of any type, and you should be able to buy from this stock into a collection of any type, including Objects.
For the main function i have this. Basically i have an stock inventory of strings, and I want to buy form this stock inventory of strings into a set of objects. However, I get this error.
add(capture#880 of ?) in java.util.Collection cannot be applied to (T)
import java.util.*;
public class lab6 {
public static void main(String[] args) {
Shop<String> turkey= new Shop<String>();
turkey.sell("pork");
turkey.sell("chicken");
turkey.print();
Set<Object> possessions= new HashSet<Object>();
turkey.buy(2,possessions);
for(String e:possessions)
System.out.println(e);
}
}
Then this is the class file.
import java.util.*;
public class Shop<T> {
List<T> stock;
public Shop() { stock = new LinkedList<T>(); }
public T buy() {
return stock.remove(0);
}
void sell(T item) {
stock.add(item);
}
void buy(int n, Collection<?> items) {
for (T e : stock.subList(0, n)) {
items.add(e);
}
for (int i=0; i<n; ++i) stock.remove(0);
}
}
Replace your buy method with this:
void buy(int n, Collection<T> items) {
for (T e : stock.subList(0, n)) {
items.add(e);
}
for (int i=0; i<n; ++i) stock.remove(0);
}
You were using Collection<?>
EDIT:
Also change your main to this:
public static void main(final String[] args) {
final Shop<String> turkey = new Shop<String>();
turkey.sell("pork");
turkey.sell("chicken");
turkey.print();
final Set<String> possessions = new HashSet<String>();
turkey.buy(2, possessions);
for (final String e : possessions) {
System.out.println(e);
}
}
and write a print() method in Shop.
The problem here is that Collection<?> can contain any type of object, and T may not be a subtype of the ? type. For example, you could pass in a Collection<Integer> and if T is String, clearly you can't do items.add(e).
You need to make sure that the Collection holds a supertype of T so that it is always valid to add a T, so try something like:
void buy(int n, Collection<? super T> items)

Make my own FIFO Queue class for my own class object to fill it?

I am trying to make a FIFO Queue that is filled with my own class object.
I found this example but if I replace < E > with < PCB > it does not work:
import java.util.LinkedList;
public class SimpleQueue<E> {
private LinkedList<E> list = new LinkedList<E>();
public void put(E o) {
list.addLast(o);
}
public E get() {
if (list.isEmpty()) {
return null;
}
return list.removeFirst();
}
public Object[] getAll() {
Object[] res = new Object[list.size()];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
list.clear();
return res;
}
public E peek() {
return list.getFirst();
}
public boolean isEmpty() {
return list.isEmpty();
}
public int size() {
return list.size();
}
}
E is a type parameter. In simple terms, you can consider it as a 'template' which can be used to create a queue that can hold instances of one particular class.
You can create a queue of your PCB objects as follows:
SimpleQueue<PCB> queue = new SimpleQueue<PCB>();
Java Generics FAQs is a good resource if you want to learn more about Java generics.
public class MyQueue{
int arr[]=new int[10];
int i=0;
int j=0;
public void inn(int a)
{
System.out.println("You hava entered :"+a);
arr[i]=a;
i=i+1;
}
public int out()
{
return arr[j++];
}
public static void main(String args[])
{
MyQueue q=new MyQueue();
q.inn(4);
q.inn(3);
q.inn(46);
q.inn(44);
q.inn(43);
System.out.println(q.out());
System.out.println(q.out());
System.out.println(q.out());
System.out.println(q.out());
}
}
The sun's generic tutorial says following:
We recommend that you use pithy
(single character if possible) yet
evocative names for formal type
parameters. It’s best to avoid lower 3
case characters in those names, making
it easy to distinguish formal type
parameters from ordinary classes and
interfaces. Many container types use
E, for element, as in the examples
above.
So, it can't be the problem that you changed it to PCB.
But if PCB is the only class of which you want to store objects, you don't have to create a generic class. Just remove <PCB> from your class definition line and replace all E's with PCB:
public class SimpleQueue
{
LinkedList<PCB> list = new LinkedList<PCB>();
....
public PCB peek()
{
return list.getFist();
}
}

Categories

Resources