How to initialise and access an array of collection objects - java

I want to create an array of sets and access them for my program. But, since arrays cannot be merged with generic types, I have wrapped my HashSet class inside another class as given below.
Class MyClass{
private HashSet<Integer> myKeys;
public boolean add(Integer i) { return myKeys.add(i); }
public boolean contains(Integer i){ return myKeys.contains(i); }
public boolean remove(Integer i){ return myKeys.remove(i); }
}
Later in my main() method, I had put the below code:
public static void main(String []args){
System.out.println("Hello World");
MySets[] keys= new MySets[2];
keys[1].add(1);
keys[2].add(2);
keys[1].add(2);
keys[2].add(4);
System.out.println("Key 1=" +keys[1]+" Key 2=" +keys[2]);
}
I am unable to access any of the objects may be since they are not initialised as HashSets. Please suggest a possible solution to access the sets.

The objects on the array are null since you didn't initialize them.
You have to initialize them first.
You also have to initialize your HashSet.
You should work with the Set interface instead HashSet.
There's also a problem with the indexes of your array. Java indexes start from 0.
class MySets {
private Set<Integer> myKeys = new HashSet<Integer>();
public boolean add(Integer i) { return myKeys.add(i); }
public boolean contains(Integer i){ return myKeys.contains(i); }
public boolean remove(Integer i){ return myKeys.remove(i); }
}
public static void main(String []args){
System.out.println("Hello World");
MySets[] keys= new MySets[2];
keys[0] = new MySets();
keys[1] = new MySets();
keys[0].add(1);
keys[1].add(2);
keys[0].add(2);
keys[1].add(4);
System.out.println("Key 1=" +keys[0]+" Key 2=" +keys[1]);
}

Related

Reaching a variable inside of an enum element in java

I want each element of an enum to have different variables but I can't reach them.
public class Employee {
public GENERAL[] general = GENERAL.values();
public static void main(String[] args) {
Employee e = new Employee();
e.general[GENERAL.INCOME.ordinal()].salary = 10; //this line doesn't compile
}
enum GENERAL{
INCOME{
public int salary;
public int tips;
},SATIFACTION{
//some variables
},EFFICIENCY{
//some variables
};
}
}
I've tried casting to (GENERAL.INCOME) but it didn't work. Is there a way to do it? If this is not possible, what is the best work around? Thanks in advance.
Try defining variables at enum level rather than individual elements:
public static void main(String[] args) {
MainClass e = new MainClass();
e.general[GENERAL.INCOME.ordinal()].salary = 10; //this line doesn't compile
System.out.println(e.general[GENERAL.INCOME.ordinal()].salary);
}
enum GENERAL{
INCOME(0,0), SATIFACTION(0, 0), EFFICIENCY(0,0);
int salary;
int tips;
GENERAL(int salary, int tips){
this.salary = salary;
this.tips = tips;
}
}
This is because INCOME is an anonymous subclass of GENERAL, it is something like this
static class GENERAL {
public static GENERAL INCOME = new GENERAL() {
public int salary;
public int tips;
};
}
there is no way to access fields of an anonymous class in Java (except reflection)
This is the cleanest way I can do it. I still have an array that I can use to iterate. Each element of the General holds its own variables. Each element has an ordinal to use as the index number.
The problem with this approach is this cannot make use of GENERAL.values(). If a new element is added later, It must be added to the getList() method manually and in the correct order. It is easy to make mistakes when adding new elements to the code.
public class Employee {
public Object general[] = General.getList();
public static void main(String[] args) {
Employee e = new Employee();
General.Income i = (General.Income) e.general[General.Income.ordinal];
i.salary = 10; //eclipse doesn't let me to combine these 2 lines into 1 expressions.
System.out.println(i.salary);
// following lines demonstrates that the salary of the e.general[General.Income.ordinal] is changed. Not just the i.
General.Income t = (General.Income) e.general[General.Income.ordinal];
System.out.println(t.salary);
}
public static class General {
public static Object[] getList() {
Object general[] = { new Income(), new Satisfaction(), new Efficiency() };
return general;
}
public static class Income {
public static final int ordinal = 0;
public int salary;
public int tips;
}
public static class Satisfaction {
public static final int ordinal() {return 1;}//using method instead of int saves memory. (8 bytes I think. Neglettable).
// some variables
}
public static class Efficiency {
public static final int ordinal = 2;
// some variables
}
}
}
If each enumeration would contain a single value, why not use that?
You can even add a method to retrieve some descriptive name:
enum General {
INCOME, SATIFACTION, EFFICIENCY;
int value = 0;
String getName() {
switch(this) {
case INCOME:
return "salary";
case SATIFACTION:
return "etc";
}
}
}
These can be set/get by General.values()[i].value and General.INCOME.value or add setValue(int value) and getValue() methods and make value private.

How we can get Boolean value updated through other method in main method

Please ignore formatting and sentence related issues.
class ABC
{
public void change(Boolean x, Boolean y, StringBuffer s)
{
x=true;
y=true;
s.append("vinay");
}
public static void main(String a[])
{
Boolean x = false;
Boolean y = false;
x=false;
y=false;
StringBuffer s = new StringBuffer();
s.append("jasi");
ABC p= new ABC();
p.change(x,y,s);
System.out.println(x);
System.out.println(y);
System.out.println(s);
}
}
i want to get all changes which i made in change() method in main() method for Boolean x,y as we are getting s modified in main function.
Is there any way by which we can get modified value in main method.
Java passes arguments by value, so all changes done in your change() method are not visible for caller.
In order to do what you want you can either:
1. define this variable as class members.
2. return them as a return value of the method. Yes, you are limited by only one return value but if your want to can create array of booleans or create specal class that contains both.
3. You can pass to method mutable container that contains boolean. One of the ways is to use AtomicBoolean for this:
public void change(AtomicBoolean x, AtomicBoolean y, StringBuffer s) {
x.set(true);
y.set(true);
s.append("vinay");
}
public static void main(String a[]) {
AtomicBoolean x = new AtomicBoolean(false);
Boolean y = = new AtomicBoolean(false);
change(x, y);
System.out.println(x.get() + ", " + y.get()); // will print true true
}
Options:
Place the variables outside of the two methods (as class variables)
Create an array (there for referencing an address instead of a value).
Create a new Object that contains these two Boolean values (create a new class or use an ArrayList/HashMap/etc)
AtomicBoolean
Option 1:
class ABC
{
Boolean x = false;
Boolean y = false;
public void change(StringBuffer s)
{
//code
}
public static void main(String a[])
{
//code
p.change(s);
//code
}
}
Option 2:
class ABC
{
public void change(Boolean b, StringBuffer s)
{
b[0] = true;
b[1] = true;
//code
}
public static void main(String a[])
{
Boolean[] b = new Boolean[2];
b[0] = false;
b[1] = false;
//code
p.change(b, s);
//code
}
}
Java is pass-by-value so when you pass the boolean here p.change(x,y,s); it will treat as pass by value and when you initialized the boolean from the change method
x=true;
y=true;
it wont grab that reference but will get destroyed when it is out of scope
You can transform your boolean as static var, you'll call them with ABC.x and define just after the class with public static boolean x; It'll looks like
class ABC
{
public static boolean x;
In Java the arguments are passed by value, not as pointers, so the variables that you passed to the function have their values copied to local variables in the method, so all the changes only affects that local copy.
what you can do is get global variables, or get a return to your function.
att.

memory management using linked list

This is a homework question in relation to memory management implementation using linked lists.
Each memory process requests of a particular size of memory that must be contiguously large enough to fit the memory and then allocate the process.When a job terminates,its allowed memory becomes free.
This is the java code I wrote for this.
public class PartitionNode{
int beginAddress;
int endAddress;
boolean holeFree;
int processId;
PartitionNode next;
public PartitionNode(int begin,int end){
beginAddress=begin;
endAddress=end;
holeFree=true;
processId=-1;
next=null;
}
public PartitionNode(){}
public PartitionNode(int begin,int end,int i){
beginAddress=begin;
endAddress=end;
holeFree=false;
processId=i;
}
}
public class Partition{
private PartitionNode head;
public PartitionNode current;
public int begin;
public int end;
public PartitionNode newPartition;
public Partition(int beginAddress,int endAddress,int a){
head=new PartitionNode(beginAddress,endAddress);
begin=beginAddress;
end=endAddress;
current=head;
}
public Partition(int beginAddress,int endAddress){
current=new PartitionNode(beginAddress,endAddress);
}
public void addProcess(int size,int id){
if((current.endAddress-current.beginAddress>=size)&& current.holeFree==true){
newPartition=new PartitionNode(current.beginAddress,current.beginAddress+size-1,id);
newPartition.next=refresh();
System.out.println("beginAddress"+newPartition.beginAddress);
System.out.println("endAddress"+newPartition.endAddress);
}
}
public void print(){
System.out.println("beginAddress"+newPartition.beginAddress);
System.out.println("endAddress"+newPartition.endAddress);
}
public PartitionNode refresh(){
current=new PartitionNode(newPartition.endAddress+1,end);
return current;
}
public void deleteProcess(int process){
PartitionNode temp=head;
while(temp.next!=null){
System.out.println(temp.processId);
temp=temp.next;
}
}
public static void main (String args[]){
Partition p=new Partition(300,3000,1);
p.addProcess(500,1);
p.addProcess(800,2);
p.addProcess(400,3);
p.deleteProcess(5);
System.out.println(p.head.beginAddress);
}
}
I have two questions.
I have to have a constructor as
public Partition(int beginAddress,int endAddress,int a){
head=new PartitionNode(beginAddress,endAddress);
begin=beginAddress;
end=endAddress;
current=head;
}
where int a is of no use.It is just there to make sure that this constructor's argument list is different from
public Partition(int beginAddress,int endAddress){
current=new PartitionNode(beginAddress,endAddress);
}
Because of this now I have to call as Partition p=new Partition(300,3000,1); with 1 being useless.
How can I get rid of this problem.
My next question is implementing method to delete a process.
public void deleteProcess(int process){
PartitionNode temp=head;
while(temp.next!=null){
System.out.println(temp.processId);
temp=temp.next;
}
}
The while loop doesn't get executed.What's wrong with that?
Can someone please help me to correct the mistakes?
Comment-as-answer:
You should split this into two questions. You can get rid of the need for the useless concstructor arg by using static factory methods to create your object, rather than the constructor directly. They allow you to name different ways to create an instance of a class. Make the constructor private while having public static methods that return a new instance of the class. That will allow you to use the same parameters for a "constructor", while having the ability to create and return a unique instance:
class Example {
public static void main(String[] args) {
Object first = Object.createObject(1, 2);
Object second = Object.createAndStore(1, 2);
}
}
class Object {
private int a, b;
//private constructor ensures need for methods
private Object(int a, int b) {
//create node
}
//the factory methods
public static Object createObject(int a, int b) {
return new Object(a, b);
}
public static Object createAndStore(int a, int b) {
Object ob = new Object();
//store vars using ob
return ob;
}
}
As for the loop part, where do you init temp.next? I see you initialize temp with head, but I don't see where you initialize it.
Also, I highly suggest changing the title of this question to more fit the issues

Set ordered by "add() count"

I'm trying to implement a Set which is ordered by the count of additions like this:
public class App {
public static void main(String args[]) {
FrequencyOrderedTreeSet<String> set = new FrequencyOrderedTreeSet<String>();
set.add("bar");
set.add("foo");
set.add("foo");
Iterator<String> i = set.iterator();
while (i.hasNext()) {
System.out.print(i.next());
}
// prints "foobar"
}
}
I've created a protected class FrequencyOrderedTreeSet.Element which implements Comparable and has a T entry and an int frequency property and extended TreeSet<FrequencyOrderedTreeSet.Element> with FrequencyOrderedTreeSet<T> and overrode the compareTo and equals methods on the Element.
One problem is that I can't override the add() method because of type erasure problems and also I can't call instanceof Element in the equals method, because in case object given to it is an Element, I have to compare their entries, but if it's not, I have to compare the object itself to this.entry.
In the add method I create a new element, find the element with the same entry in the set, set the frequency on the new element to "old+1", remove the old one and add the new one. I'm not even sure this is the best way to do this or if it would work even because the other problems I described.
The question is: what's the best way to implement such data structure? In case I'm somehow on the right track - how can I circumvent the problems I've mentioned above?
Here's a basic implementation. It's not the most optimal and will take some more work if you want to implement the full Set interface.
public class FrequencySet<T> implements Iterable<T>
{
private TreeSet<T> set;
private HashMap<T, Integer> elements = new HashMap<T, Integer>();
public FrequencySet()
{
set = new TreeSet<T>(new Comparator<T>()
{
public int compare(T o1, T o2)
{
return elements.get(o2)-elements.get(o1);
}
});
}
public void add(T t)
{
Integer i = elements.get(t);
elements.put(t, i == null ? 1 : i+1);
set.remove(t);
set.add(t);
}
public Iterator<T> iterator() {return set.iterator();}
public static void main(String [] args)
{
FrequencySet<String> fset = new FrequencySet<String>();
fset.add("foo");
fset.add("bar");
fset.add("foo");
for (String s : fset)
System.out.print(s);
System.out.println();
fset.add("bar");
fset.add("bar");
for (String s : fset)
System.out.print(s);
}
}
The key is in the add method. We change the counter for the given object (which changes the relation order), remove it from the backing set and put it back in.
This works the other way (count is increased when you use GET)
#SuppressWarnings("rawtypes")
final class Cache implements Comparable {
private String key;
private String value;
private int counter;
public String getValue() {
counter++;
return value;
}
private void setValue(String value) { this.value = value; }
public String getKey() { return key; }
private void setKey(String key) { this.key = key; }
public int getCounter() { return counter; }
public void setCounter(int counter) { this.counter = counter; }
public Cache(String key, String value) {
this.setKey(key);
this.setValue(value);
setCounter(0);
}
#Override
public int compareTo(Object arg0) {
if(!(arg0 instanceof Cache)) {
throw new ClassCastException();
}
return this.getCounter() - ((Cache) arg0).getCounter();
}
}

Converting an Enumeration to Iterator

I have a problem on a worksheet which is to create an adapter to convert an Enumeration to an Iterator. When I try to run the following code I get a null pointer exception.
import java.util.Vector;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
public class ConvertEnumeration {
public static void main(String [] args) {
int [] ourArray = {0,1,2,3,4,5,6,7,8,9};
Vector vector = new Vector(Arrays.asList(ourArray));
//Get Enumerator
Enumeration enumerator = vector.elements();
EnumerationToIterator enumToIt = new EnumerationToIterator(enumerator);
while(enumToIt.hasNext()) {
System.out.println(enumToIt.next());
}
}
}
//Convert our enumeration to Iterator!
class EnumerationToIterator implements Iterator {
//Our enumeration
Enumeration enmueration;
//Constructor
public EnumerationToIterator(Enumeration enmueration){
enmueration = this.enmueration;
}
//Our Methods
public boolean hasNext(){
return enmueration.hasMoreElements();
}
public Object next(){
return enmueration.nextElement();
}
public void remove(){
throw new UnsupportedOperationException();
}
}
Another point to note is that I can not print out the int's from the Enumeration after I have created it in the first place.
Java 5 and Later
No need to reinvent the wheel. Just use Collections.list(Enumeration<T> e), which returns an ArrayList<T>. Then use ArrayList.iterator() to get an Iterator.
Java 9 and Later
Enumerations now have a method to convert directly to an iterator:
enumeration.asIterator();
Java 9 offers a new default method: Iterator<E> asIterator()
Wrong assignment in your constructor. It needs to be this.enmueration = enmueration;
enmueration is the constructor argument, and this.enmueration is the object attribute.
public class ConvertEnumeration {
public static void main(String [] args) {
// int [] ourArray = {0,1,2,3,4,5,6,7,8,9};
Vector<Integer> vector = new Vector<Integer>(Arrays.asList(0,1,2,3,4,5,6,7,8,9));
//Get Enumerator
Enumeration<Integer> enumerator = vector.elements();
EnumerationToIterator<Integer> enumToIt = new EnumerationToIterator<Integer>(enumerator);
while(enumToIt.hasNext()) {
System.out.println(enumToIt.next());
}
}
}
//Convert our enumeration to Iterator!
class EnumerationToIterator<T> implements Iterator<T> {
//Our enumeration
Enumeration<T> enmueration;
//Constructor
public EnumerationToIterator(Enumeration<T> enmueration){
this.enmueration = enmueration;
}
//Our Methods
public boolean hasNext(){
return enmueration.hasMoreElements();
}
public T next(){
return enmueration.nextElement();
}
public void remove(){
throw new UnsupportedOperationException();
}
}

Categories