memory management using linked list - java

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

Related

In java, can nested class object use the enclosing class method?

I created a simple list class. What I want to do is to create a method in SLList to give the size a SLList object. I want to do it recursively, however, the following size() method I created just does not work. I know other ways to realize it such as creating a helper method. But what I am curious about is that why does my size() does not work? The error message is the "size() is undefined for SLList.IntNode". Why? Since I made the nested IntMode class just public and non-static, why it cannot use the method that is defined in SLList class?
public class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first.next == null) {
return 1;
}
return 1 + first.next.size();
}
}
I am just new to Java, and quite confused about the private and static things, especially when it comes to the Class. Thank you for anyone answering me.
You can fiddle it by adding an extra private method but it's not particularly easy to reason about. I would avoid doing it this way unless absolutely necessary.
class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
private int theSize()
{
return size();
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first.next == null) {
return 1;
}
return 1 + first.next.theSize();
}
}
Reason is : your method size() is in class SLList.
Hence it cannot be accessed by nested inner class IntNode.
size() is a method of SLList, not IntNode. You can refer to outer class method inside IntNode as follows:
public class SLList {
public class IntNode {
...
public int size() {
return SLList.this.size();
}
}
...
public static int size() {
...
}
}
Add a size method to IntNode class and access it from SLList size method to calculate the entire size of the list. The following code snippet is self explanatory. For more information about nested classes refer https://www.programiz.com/java-programming/nested-inner-class
public class SLList {
public class IntNode {
public int item;
public IntNode next;
public IntNode(int i, IntNode n) {
item = i;
next = n;
}
public int size() {
IntNode tmp = next;
if (tmp == null) {
return 1;
}
return 1 + tmp.size();
}
}
private IntNode first;
public SLList(int x) {
first = new IntNode(x, null);
}
public int size() {
if (first == null)
return 0;
return first.size();
}
public static void main(String[] args) {
SLList list = new SLList(10);
list.first.next = list.new IntNode(20, null);
list.first.next.next = list.new IntNode(30, null);
list.first.next.next.next = list.new IntNode(40, null);
System.out.println(list.size());
}
}

How to initialise and access an array of collection objects

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]);
}

Not sure about Singleton

If I have a singleton class like:
public class MySingleton(){
private static MySingleton istance;
private int element;
private MySingleton(){element = 10;}
public static MySingleton getIstance() {
if(istance == null)
istance = new Mysingleton();
return istance;
}
public void setElement(int i ){
element = i;
}
public int getElement(){
return element;
}
}
and I want to change element's value by calling
MySingleton.getIstance().setElement(20)
Will it change the element value for the istance? Here's an example:
... main () {
MySingleton.getIstance().setElement(20);
System.out.prinln(MySingleton.getIstance().getElement());
// It displays 10, why ?
I suggest you use an enum as it is simpler and thread safe (but not your getter/setter)
public enum MySingleton() {
INSTANCE;
private int element = 10;
public void setElement(int element) { this.element = element; }
public int getElement() { return element; }
}
MySingleton.INSTANCE.setElement(20);
System.out.prinln(MySingleton.INSTANCE.getElement()); // prints 20.
I'm not sure if your code block above was copied in or just retyped, but there were a few basic compilation issues I saw with it - when you're setting MySingleton in getInstance, you need to check capitalization. Also, your class declaration shouldn't have (parentheses). After fixing these two things and running basic main, I got 20.
This is the same as what you had - no synchronization or anything else, but on a single thread it doesn't seem necessary.
public class MySingleton{
private static MySingleton istance;
private int element;
private MySingleton(){element = 10;}
public static MySingleton getIstance() {
if(istance == null)
istance = new MySingleton();
return istance;
}
public void setElement(int i ){
element = i;
}
public int getElement(){
return element;
}
public static void main(String[] args) {
System.out.println(MySingleton.getIstance().getElement());
MySingleton.getIstance().setElement(20);
System.out.println(MySingleton.getIstance().getElement());
}
}
should have an output of
10
20
Im not sure if your code really work, how azurefrog say, make your code synchronized, and in youre line public static getIstance() { you need to set the return type.

When instantiating a method that returns a variable...?

Basically, I want to make sure that I'm doing this right. I'm calling these methods in another class. The methods specify to return a variable, so when instantiating them, should I be placing null in the parenthesis? I just want to make sure I'm doing this right.
public class IntSLList {
protected static IntSLLNode head, tail;
public void createInst(){
new IntSLList().isEmpty();
new IntSLList().addToHead(null);
new IntSLList().addToTail(null,null);
new IntSLList().deleteFromTail();
new IntSLList().printAll();
new IntSLList().isInList(null);
new IntSLList().delete(null);
}
public IntSLList() {
//code
}
public static boolean isEmpty() {
//code }
public static void addToHead(String AN) {
//code
}
public static void addToTail(String AN, Double AB) {
//code
}
public static String deleteFromHead() { // delete the head and return its info;
//code
}
public static String deleteFromTail() { // delete the tail and return its info;
//code
}
public static void printAll() {
//code
}
public static boolean isInList(String AN) {
//code
}
public static void delete(String AN){
//code
}}
Thanks everyone in advance!
You don't need to instantiate methods at all, they are already "prepared for use" when your list gets instantiated.
What you want to do is remove the static keyword from the methods: It means that the methods are defined "global" for the whole class instead of just for one specific list.
Update: This is the list class as I imagine it should be
import java.util.ArrayList;
public class IntSLList {
protected int head,tail;
//I'll use this as examplelist, so I can omit the list implementation
private ArrayList<Integer> dataList;
public IntSLList(){
//Do initalization
dataList = new ArrayList<>();
}
public void addToHead(int node){
dataList.add(0, node);
}
public void addToTail(int node){
dataList.add(node);
}
public boolean isEmpty(){
return dataList.isEmpty();
}
// ... snip other list methods here ...
}
You can use/access it like this:
public class ListMain {
public static void main(String[] args){
IntSLList myList = new IntSLList();
myList.addToHead(1);
myList.addToTail(2);
System.out.println("myList.isEmpty() = " + myList.isEmpty());
}
}

How would i compare two objects in custom tree set implementation?

I need to compare two objects in insert method off the tree set. But i am unable to fathom out where and how to implement Comparable or Comparator. My code looks as follows:
This is my Node creation for the binary tree.
Node.java
public class Node {
private Object data;
private Node left, right;
//initial case when a Node of a binary tree gets created. both left and right subtrees point to null
public Node (){
left = right = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
This is my MyBinaryTree class where i need to implement insert method:
MyBinaryTree.java
public class MyBinaryTree implements Comparable<Node> {
Node root;
public MyBinaryTree(){
root = null;
}
void insert(Object x){
Node newrec = new Node(); //Node constructor gets called and sets up a root node with empty
//subtrees
newrec.setData(x);
if(root == null){
root = newrec;
}
else{
Node a,b;
a = b = root;
while(a!=null){
b=a;
if( ( newrec.getData() ).compareTo( a.getData() ) ) {
i am stuck here! how would i compare these objects using Comparable?
}
}
}
}
void inorder(Node root){
}
#Override
public int compareTo(Node o) {
// TODO Auto-generated method stub
int i = (o.)
return 0;
}
}
You need to be able to compare, not just nodes, but the data contained in those nodes. That means that your Node either needs to be limited to taking objects that are Comparable, or your tree needs to take a Comparator that it can use to compare them.
If you really want to support both, then when the time comes to do the comparison, if a Comparator has been provided, use its compare method, otherwise cast the data to Comparable<? super E> where E is the type of Node data (see below), and then use its compareTo method.
That brings me to the next point. Your Node class should probably not simply contain Object as its data, but instead be declared as Node<E> implements Comparable<Node<E>>, and then your tree can be declared as MyBinaryTree<E>. I would also change the constructor for Node to take the data as a parameter, rather than calling the setter immediately after creating one. There is no reason you would ever want to create a Node with no data.
I would strongly suggest looking through the source code for some of the generic collections in the java.util package, which comes with the JDK. In particular, I referred to the source of TreeMap.java to see how they handled both Comparable and non-Comparable elements, since the class isn't declared in such a way as to require the elements to be Comparable. (If they aren't, and there is no Comparator, a ClassCastException would occur where they try to cast the object to Comparable<? super K>.) Seeing how they have implemented similar code will be a great help to you. You may also want to review Java generics.
Please refer below code
package com.example.treeset;
import java.util.Comparator;
import java.util.TreeSet;
public class MyCompUser {
public static void main(String a[]){
//By using name comparator (String comparison)
TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp());
nameComp.add(new Empl("Ram",3000));
nameComp.add(new Empl("John",6000));
nameComp.add(new Empl("Crish",2000));
nameComp.add(new Empl("Tom",2400));
for(Empl e:nameComp){
System.out.println(e);
}
System.out.println("===========================");
//By using salary comparator (int comparison)
TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp());
salComp.add(new Empl("Ram",3000));
salComp.add(new Empl("John",6000));
salComp.add(new Empl("Crish",2000));
salComp.add(new Empl("Tom",2400));
for(Empl e:salComp){
System.out.println(e);
}
}
}
class MyNameComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
return e1.getName().compareTo(e2.getName());
}
}
class MySalaryComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
if(e1.getSalary() > e2.getSalary()){
return 1;
} else {
return -1;
}
}
}
class Empl{
private String name;
private int salary;
public Empl(String n, int s){
this.name = n;
this.salary = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString(){
return "Name: "+this.name+"-- Salary: "+this.salary;
}
}

Categories