I have a problem that I can't get around how to solve, I'm currently working on a mini filesystem wich requiers to create an massive amount of objects (in theory). I currently tried ArrayList<INode> nodes = new ArrayList<INode>(); and then when I add an object(INode) nodes.add(new INodeDirectory(paths[i]));
But when I check later if this node excist in nodesit doesent, any suggestions on how to solve this or what to use instead?
MiniFs class:
package se.kth.id1020.minifs;
import edu.princeton.cs.introcs.StdOut;
import java.util.HashMap;
public class MiniFs implements FileSystem {
private final INodeDirectory root;
private HashMap<String,Integer> map = new HashMap<String, Integer>();
private int n = 0; //Number of objects created
priate ArrayList<INode> nodes = new ArrayList<INode>();
public MiniFs() {
root = new INodeDirectory("/");
map.put("/",n);
}
//Create a directory/folder
#Override
public void mkdir(String path) {
String paths[] = path.split("/");
if(paths.length == 2){
nodes.add(new INode<directory(paths[paths.length - 1]));
n++;
map.put(paths[1],n);
StdOut.println("OK.");
}
else{
for(int i = 1; i < paths.length; i++){
if(i == paths.length - 1){
if(map.containsKey(paths[i])){
StdOut.println("Directory already excists");
}
else{
nodes.add(new INodeDirectory(paths[i]));
n++;
map.put(paths[i],n);
StdOut.println("OK.");
}
}
else if(map.containsKey(paths[i]) == false){
throw new UnsupportedOperationException("Error: you have to create " + paths[i] + " first!");
}
}
}
}
//Create a file
#Override
public void touch(String path) {
String paths[] = path.split("/");
if(paths.length == 2){
nodes.add(new INodeFile(paths[paths.length - 1]));
n++;
map.put(paths[paths.length - 1], n);
StdOut.println("OK.");
}
else{
for(int i = 1; i < paths.length; i++){
if(i == paths.length - 1){
if(map.containsKey(paths[i])){
StdOut.println("File already excists");
}
else{
nodes.add(new INodeFile(paths[i]));
n++;
map.put(paths[i],n);
StdOut.println("OK.");
}
}
else if(map.containsKey(paths[i]) == false){
throw new UnsupportedOperationException("You have to create " + paths[i] + " first!");
}
}
}
}
//Create a pointer to a file or directory
#Override
public void ln (String path, String target){
String paths[] = path.split("/");
String targets[] = target.split("/");
if(paths.length == 2 && targets.length == 2 && map.containsKey(paths[1]) && map.containsKey(targets[1])){
int pathIndex = nodes.indexOf(paths[1]);
int targetIndex = nodes.indexOf(targets[1]);
nodes.get(pathIndex).setPointer(nodes.get(targetIndex));
StdOut.println("OK.");
}
}
}
INode class:
package se.kth.id1020.minifs;
public abstract class INode {
private String name;
private ArrayList<INode> pointer;
private long accessTime;
public INode(String name) {
this.name = name;
this.accessTime = System.currentTimeMillis();
}
public void setPointer(INode n) {
pointer.add(n);
}
public long getAccessTime() {
return accessTime;
}
public void setAccessTime(long accessTime) {
this.accessTime = accessTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
INodeDirectory class:
package se.kth.id1020.minifs;
public class INodeDirectory extends INode {
public INodeDirectory(String name) {
super(name);
}
}
INodeFile class:
package se.kth.id1020.minifs;
public class INodeFile extends INode {
public INodeFile(String name) {
super(name);
}
}
You need to override .equals() for anything that you're putting into an ArrayList and checking with .contains() or .indexOf().
It's very easy to get your IDE to help with this. I'd strongly recommend implementing .hashCode() as well, in case you want to use a HashMap later on (otherwise you'll hit a similar problem).
You have an even more serious problem, though, which is that when you check whether it's in there, you're passing a String to indexOf() rather than an INode. This will fail because the list doesn't store strings. If you want to check whether a node is there, you need to create a new node from the String, and check whether that's present.
You are trying to check if the ArrayList contains a certain instance of the INode class. However, you don't define how to compare tow INodes. ArrayList.contains() uses the INode class's default .equals() method, which will not actually work unless it is overriden using #Override in the INode class. If you are using Eclipse, you can easily generate the .equals() and .hashCode() functions by pressing Alt+Shift+S and selecting "Generate hashcode() and equals()
Related
Good evening!
I have been trying to get things done for the whole day and I have definitly reached my limit. I have created a class "entry" that consists of a name (String), an adress (String) and a tel number (int).
Furthermore, I have created a class called "phoneDirectory" and it consists of an array from the class entry.
My goal is it right now to create a method that searches that array for a name given and outputs the whole entry.
Things I have tried so far:
public void searchEntry(String name) {
for(int i = 0; i < directory.length; i++) {
if(directory[i] != null) {
System.out.println(directory[i].contains(name));
}else {
System.out.println("no entry");
}
}
}
}
public void searchEntry(String name) {
for(int i = 0; i < directory.length; i++) {
if(directory[i] != null) {
if(Arrays.asList(directory[i]).contains(name)); //It says: "Unlikely argument type String for contains(Object) on a Collection <entry>"
}else {
System.out.println("no entry");
}
}
}
}
public void searchEntry(String name) {
for(int i = 0; i < directory.length; i++) {
if(directory[i] != null) {
if(directory[i].contains(name)){ //The method contains(String) is undefinded for the type entry
}else {
System.out.println("no entry");
}
}
}
}
And many others by searching with google but nothing worked or gave me a "no entry" even though there is an entry with the String.
I would really appreciate it if someone could help me with this one. Thanks a lot.
The code for the 2 classes:
public class Entry{
private String name;
private String adress;
private int number;
public Entry(String name, String adress, int number) {
super();
this.name = name;
this.adress = adress;
this.number= number;
}
#Override
public String toString() {
return "\n" + name + ": " + adress + " , " + number+ "\n";
}
public class PhoneDirectory{
private Entry[] directory;
public PhoneDirectory(Entry[] directory) {
super();
this.directory= directory;
}
As mentioned in the question PhoneDirectory class has a Entry type array named directory and you have implemented the searchEntry method.
You can implement searchEntry as shown below:
public void searchEntry(String name) {
for(int i = 0; i < directory.length; i++) {
if(directory[i] != null) {
if(directory[i].getName().equals(name)){
System.out.println(directory[i]);
break; // assuming name is unique so you don't need to continue looping once name is found
}
}else {
System.out.println("no entry");
}
}
}
Also you need to implement getters inside your Entry class as all attributes are private, so that you can access them inside Directory class.
You are calling .contains() on the Entry instead of the name String.
You can just use Java Streams to search for results:
public void searchEntry(String name) {
Arrays.stream(directory)
.filter(e -> e.name.contains(name))
.forEach(System.out::println);
}
Or if you want to print a message if no entry is found you can use this:
public void searchEntry(String name) {
List<Entry> matches = Arrays.stream(directory)
.filter(e -> e.name.contains(name))
.collect(Collectors.toList());
if (matches.isEmpty()) {
System.out.println("no entry");
} else {
matches.forEach(System.out::println);
}
}
Sorry for the unformatted message.
If 'directory' type is Array of entry, then you can't find there String (which is 'name')
if(Arrays.asList(directory[i]).contains(name));
You have to compare name which you want to find and name from entry. For example:
You have those classes:
public class Entry {
private String name;
public String getName() {
return name;
}
}
public class PhoneDirectory {
private Entry[] entries;
public Entry searchEntry(String name) {
for (Entry entry : entries) {
if (entry.getName().equals(name)) {
return entry;
}
}
throw new RuntimeException("There is no entry with name: "+name);
}
}
After that, I would advise if you don't know how many entries contain phoneDirectory then use List instead of Array.
One more thing, if you search for something, a user (and you) expect this 'something' as a result.
import java.util.ArrayList;
public class Folder extends AbstractFile
{
//Replace previous ArrayLists with a single
//ArrayList of AbstractFile references
private ArrayList<AbstractFile> files = new ArrayList();
AbstractFile abstractfile;
/**
* Constructor for objects of class Folder
*/
public Folder(String name)
{
super();
this.name = name;
}
// replace previous add methods
// with a single add(AbstractFile fileObject) method
public boolean add(AbstractFile fileObject)
{
return files.add(fileObject);
}
#Override
public int size()
{
int size =0; // size holds the running total
for (AbstractFile file : files){ // for each AbsFile ref
size+=file.size(); //call size() and update the running total
}
return size; // return the final value
}
#Override
public int getNumFiles(){
int numFiles = 0;
for(AbstractFile file: files)
{
numFiles += file.getNumFiles();
}
return numFiles;// default value
}
#Override
public int getNumFolders(){
int numFolders = 0;
// for(AbstractFile file: files)
// {
// if(file instanceof Folder)
// {
// numFolders += file.getNumFolders();
// }
// }
// return numFolders;// default value
for (Object e : files)
{
if (e instanceof Folder)
{
numFolders += e.getNumFolders();
}
}
return numFolders;// default value
}
#Override
public AbstractFile find(String name){
//TODO Later - not in mini assignment
return null;
}
}
AbstractFile Class
public abstract class AbstractFile
{
// instance variables -
String name;
public abstract int size();
public abstract int getNumFiles();
public abstract int getNumFolders();
public abstract AbstractFile find(String name);
public String getName(){
return name;
}
}
FileSystem Class- for testing
public class FileSystem
{
public static void main(String[] args)
{
FileSystem fileSystem = new FileSystem();
fileSystem.fileTest1();
}
public void fileTest1(){
Folder documents = new Folder("Documents");
Folder music = new Folder("Music");
Folder photos = new Folder("Photos");
documents.add(music);
documents.add(photos);
File assign1 = new File("assign1.doc");
documents.add(assign1);
Folder dylan = new Folder("Dylan");
music.add(dylan);
Folder band = new Folder("The Band");
music.add(band);
File family = new File("family.jpg");
photos.add(family);
File tambourine = new File("tambourine.mp3");
dylan.add(tambourine);
File dixie = new File("dixie.mp3");
band.add(dixie);
File weight = new File("weight.mp3");
band.add(weight);
String contents1 = ("Hey, mister, can you tell me ");
String contents2 = ("Hey Mr Tambourine Man");
String contents3 = ("The night they drove old dixie down");
String contents4 = ("fee fi fo fum");
weight.setContents(contents1); // add contents to each File
tambourine.setContents(contents2);
dixie.setContents(contents3);
assign1.setContents(contents4);
//********test for size()****************
int expected = contents1.length() + contents2.length() + contents3.length() + contents4.length();
int result = documents.size();
if(result==expected){ // test fro equality
System.out.println("size() works");
}else{
System.out.println("size() doesn't work");
}
//*****************************************
//*****************test for getNumFiles()******************
expected =5;// what value should expected be set to?
result = documents.getNumFiles();
if(result==expected){ // test fro equality
System.out.println("NumFiles() works");
}else{
System.out.println("NumFiles() doesn't work");
}
//output the results of the test for equality
// **************************************
//*****************test for getNumFiles()******************
expected = 5; // what value should expected be set to?
result = documents.getNumFolders();
if(result==expected){ // test fro equality
System.out.println("NumFolder() works");
}else{
System.out.println("NumFolder() doesn't work");
System.out.printf("%d",result);
}
// **************************************
}
}
File Class
public class File extends AbstractFile
{
private String contents;
/**
* Constructor for objects of class File
*/
public File(String name)
{
super();
this.name = name;
}
public String getContents(){
return contents;
}
public void setContents(String contents){
this.contents = contents;
}
#Override
public int size()
{
if(contents==null){ //handle situation where contents may not have been set
return 0;
}
return contents.length();
}
#Override
public int getNumFiles(){
return 1; // a File object just returns 1 (it contains one File - itself)
}
#Override
public int getNumFolders(){
//TODO
return 0;
}
#Override
public AbstractFile find(String name){
//TODO Later - not in mini assignment
return null;
}
}
Hi, So Basically I'm having trouble with the getNumFolders(method) I have a test class created with 5 folders and these are stored in an ArrayList of type AbstractFile called files. I am trying to loop through this ArrayList to count the folders, bare in mind this ArrayList also contains files, so they must not be counted.
I would appreciate any help.
Thanks so much!
Simply if you want to count the number of Folder instances, then below should do the work.
public int getNumFolders() {
int numFolders = 0;
for(AbstractFile file: files) {
if(file instanceof Folder) {
numFolders++;
}
}
return numFolders;
}
and expectedValue should be 2 here accroding to your test case.
in fileTest1() method of your test case,
expected = 2; // this should be two because there are two folders called music and photos in documents folder
result = documents.getNumFolders();
I know this must be a fundamental design problem because I clearly can't do this. I want to call the ownGrokk, ownTyce, etc methods from another class depending on the value of the integer assigned to OwnedSpirits(int). This in turn fills arrays.
The problem is, I do this multiple times, and doing it from another class it seems like I have to make a new object every time to pass the new int argument, and doing so resets the value of spiritInstance. And, since that resets to zero, the arrays don't fill properly. I try to print out my array values later and I get an "ArrayIndexOutOfBoundsException".
public class OwnedSpirits {
private int spiritTypeInt = 0;
public static int spiritInstance=0;
public static int[] spiritarray = new int[9];
public static String[] spiritName = new String[9];
public static int[] party = new int[3];
public OwnedSpirits(int spiritcall){
if(spiritcall == 1){
ownGrokk();
}
if(spiritcall == 2){
ownRisp();
}
if(spiritcall == 3){
ownTyce();
}
if(spiritcall == 4){
ownDaem();
}
if(spiritcall == 5){
ownCeleste();
}
}
private void ownGrokk(){
spiritName[spiritInstance] = "Grokk";
spiritInstance++;
}
private void ownRisp(){
spiritName[spiritInstance] = "Risp";
spiritInstance++;
}
private void ownDaem(){
spiritName[spiritInstance] = "Daem";
spiritInstance++;
}
private void ownCeleste(){
spiritName[spiritInstance] = "Celeste";
spiritInstance++;
}
private void ownTyce(){
spiritName[spiritInstance] = "Tyce";
spiritInstance++;
}
and this code is in another class, where it attempts to call the methods to fill the array
buttonConfirm.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
if(xcounter==3){
for(x=0; x<3; x++){
if(setdaemtrue == true){
new OwnedSpirits(4);
}
if(setrisptrue == true){
new OwnedSpirits(2);
}
if(setcelestetrue == true){
new OwnedSpirits(5);
}
if(settycetrue == true){
new OwnedSpirits(3);
}
if(setgrokktrue == true){
new OwnedSpirits(1);
}
}
}
}
});
and finally in yet another class:
System.arraycopy(OwnedSpirits.spiritName, 0, partylist, 0, 3);
#Override
public void show() {
System.out.println(partylist[0]);
System.out.println(partylist[1]);
System.out.println(partylist[2]);
spiritlist.setItems(partylist);
table.add(spiritlist);
table.setFillParent(true);
stage.addActor(table);
}
If the last part is confusing, it's because I am using libgdx. the print statements are there just to try to figure out why my list was having an error
I can show you what I would do to handle Spirits, and Parties.
The Spirit class, contains name and current party its assigned to:
package com.stackoverflow.spirit;
public class Spirit {
private String name;
private Party party;
private SpiritType type;
private static int id = 0;
public static enum SpiritType {
Grokk, Risp, Tyce, Daem, Celeste
};
public Spirit(String name, SpiritType type) {
create(name, type);
}
public Spirit(SpiritType type) {
create(null, type);
}
// This is to handle Java inexistance of default parameter values.
private void create(String name, SpiritType type)
{
Spirit.id++;
this.name = (name == null) ? (type.name() + " " + id) : name;
this.type = type;
}
public String getName() {
return name;
}
public Party getParty() {
return party;
}
public SpiritType getType() {
return type;
}
/**
* Used internally by #see Party
* #param party the party this Spirit belongs
*/
public void setParty(Party party) {
this.party = party;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString()
{
return this.name;
}
}
Finally the Party class, contains a set of Spirits, you can add and remove Spirits from the party.
package com.stackoverflow.spirit;
import java.util.HashSet;
public class Party {
private HashSet<Spirit> spirits = new HashSet<Spirit>();
private static int id = 0;
private String name = "Party " + Party.id++;;
public Party() {
}
public Party(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void add(Spirit spirit) {
if (!spirits.contains(spirit)) {
spirits.add(spirit);
if (spirit.getParty() != null) {
//Remove from previous party to update the other party set
spirit.getParty().remove(spirit);
}
spirit.setParty(this);
} else {
// throw new SpiritAlreadyOnParty();
}
}
public void remove(Spirit spirit)
{
if (spirits.contains(spirit))
{
spirit.setParty(null); // You could create a default empty party for "Nature/Neutral" Spirits perhaps :)
spirits.remove(spirit);
}
else {
//throw new SpiritNotInParty();
}
}
public boolean isOnParty(Spirit spirit) {
return spirits.contains(spirit);
}
public ArrayList<Spirit> getSpirits()
{
return new ArrayList<Spirit>(spirits);
}
public int getPartySize() {
return spirits.size();
}
public String getPartyInfo()
{
StringBuilder builder = new StringBuilder();
builder.append("Party:" + this.name + " Size:" + this.spirits.size() + "\n");
for (Spirit s : spirits)
{
builder.append(s.getName() + "\n");
}
return builder.toString();
}
#Override
public String toString()
{
return this.name;
}
}
Here I use the Spirit and Party classes, you could add more functionality, like properties for party strength, magic buffs on the party, etc:
package com.stackoverflow.spirit;
import com.stackoverflow.spirit.Spirit.SpiritType;
public class Main {
public static void main(String[] args) throws java.lang.Exception {
Party griffindor = new Party("Griffindor"), slytherin = new Party(
"Slytherin");
// You can also do for (SpiritType type : SpiritType.values() then
// type.ordinal()
for (int i = 0; i < SpiritType.values().length; i++) {
griffindor.add(new Spirit(SpiritType.values()[i]));
slytherin.add(new Spirit(SpiritType.values()[i]));
}
Spirit mySpirit = new Spirit("NotAHPFan", SpiritType.Celeste);
slytherin.add(mySpirit);
System.out.println("Name of party:" + mySpirit.getParty().getName());
System.out.println("Is on griffindor?:"
+ griffindor.isOnParty(mySpirit));
// What now?
griffindor.add(mySpirit);
System.out.println("Is " + mySpirit.getName() + " on "
+ slytherin.getName() + "?:" + slytherin.isOnParty(mySpirit));
System.out.println(mySpirit.getName() + " is now on "
+ mySpirit.getParty() + "\n");
System.out.println(griffindor.getPartyInfo());
System.out.println(slytherin.getPartyInfo());
}
}
P.D: I'm not a HP fan.
public class ContactList {
private ContactNode head;
private ContactNode last;
public ContactNode current;
public ContactList value;
public ContactList() {}
public void addNode(ContactNode input) {
if (this.head == null) {
this.head = input;
this.last = input;
} else last.setNext(input);
input.setPrev(last);
this.last = input;
}
public void traverse() {
System.out.println();
current = this.head;
while (current != null) {
System.out.print(current.getName() + " ");
System.out.println("");
current = current.getNext();
}
System.out.println();
}
public void insertNewFirstNode(String value) {
ContactNode newNode = new ContactNode(value);
head = newNode;
if (last == null) {
last = head;
}
}
public void sort() {
ContactList sorted = new ContactList();
current = head;
while (current != null) {
int index = 0;
if ((current.getName() != null)) {
index = this.current.getName().compareTo(current.getName());
if (index == 1) {
sorted.insertNewFirstNode(current.getName());
}
current = current.getNext();
} else if ((current != null)) {
System.out.print(sorted + "\n");
}
}
} // end contactList
Main Method:
import java.util.Scanner;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ContactMain {
public static void main(String[] args) {
try {
FileReader filepath = new FileReader("data1.txt");
Scanner k = new Scanner(filepath);
ContactList myList = new ContactList();
while (k.hasNextLine()) {
String i = k.nextLine();
myList.addNode(new ContactNode(i));
}
myList.traverse();
myList.sort();
myList.traverse();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. ");
}
}
}
Node Class:
public class ContactNode {
private String name;
public int index;
private ContactNode prev;
public ContactNode next;
ContactNode(String a) {
name = a;
index = 0;
next = null;
prev = null;
}
public ContactNode getNext() {
return next;
}
public ContactNode getPrev() {
return prev;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
public void setNext(ContactNode newnext) {
next = newnext;
}
public void setPrev(ContactNode newprevious) {
prev = newprevious;
}
public void setName(String a) {
name = a;
}
public void setIndex(int b) {
index = b;
}
}
I am making a program for fun that reads in contact information from a text file and puts them into a Linked List. I want to create a sort() method to sort each node or name alphabetically. I've done a good amount of research and my method only prints code like: ContactList#282c0dbe, by as many lines as my text file.
what is ContactList#282c0dbe?
It is class name follow by at sign and hash code at the end, hash code of the object.All classes in Java inherit from the Object class, directly or indirectly . The Object class has some basic methods like clone(), toString(), equals(),.. etc. The default toString() method in Object prints “class name # hash code”.
What is the solution?
You need to override toString method in ContactList class because it is going to give you clear information about the object in readable format that you can understand.
The merit about overriding toString:
Help the programmer for logging and debugging of Java program
Since toString is defined in java.lang.Object and does not give valuable information, so it is
good practice to override it for subclasses.
#override
public String toString(){
// I assume name is the only field in class test
return name + " " + index;
}
For sorting, you should implement Comparator interface since your object does not have natural ordering. In better sense, if you want to define an external controllable ordering behavior, this can override the default ordering behavior
read more about Comparator interface
You need custom Comparator for sorting, and to pretty print your List you need to implement toString() in ContactList class
I want to make an array of objects and use it in different functions. I wrote this pseudocode
privat stock[] d;
privat stock example;
public void StockCheck(){
d =new stock[2];
d[0]= new stock("a","test1", 22);
d[1]= new stock("b","test2", 34);
}
#Override
public stock getStock(String name) throws StockCheckNotFoundException{
int i;
System.out.println("ok" + name + d.legth); // error
example = new stock("example","example",2);
return example;
}
In class test I make an instance of getStock and I call the function getStock stock.getStock();
I get a NullPointerExeption when I do d.length. d is null but I don't understand why.
Hmmmm. If that is in any way like your real code, then the problem is that your "constructor" isn't really a constructor, as you've declared it to return void, making it an ordinary method instead. Remove tbat "void" and it may fix the problem!
Perhaps this example of code will do what you need, using three classes
Test - the main test code
Stock - the implied code for Stock from your question
StockCheck - the corrected code from your question.
(Note: you may really want to use an ArrayList inside StockQuote so you can add and delete Stocks.)
Test class
package stackJavaExample;
public class Test {
public static void main(String[] args) {
String[] testNames = {"test1","test2","notThere"};
StockCheck mStockCheck = new StockCheck();
for (int i=0; i<testNames.length; i++) {
Stock result = mStockCheck.getStock(testNames[i]);
if (result == null) {
System.out.println("No stock for name: " + testNames[i]);
} else {
System.out.println("Found stock: " + result.getName() + ", " + result.getSymbol() + ", " + result.getValue());
}
}
}
}
Stock class
package stackJavaExample;
public class Stock {
private String symbol;
private String name;
private double value;
public Stock(String symbol, String name, double value) {
this.symbol = symbol;
this.name = name;
this.value = value;
}
public String getSymbol() { return symbol;}
public String getName() { return name;}
public double getValue() {return value;}
}
StockCheck class
package stackJavaExample;
public class StockCheck {
private Stock[] d;
public StockCheck() {
d = new Stock[2];
d[0] = new Stock("a","test1", 22);
d[1] = new Stock("b","test2", 34);
}
public Stock getStock(String name) {
for (int i=0; i < d.length; i++) {
if (d[i].getName().equalsIgnoreCase(name)) {
return d[i];
}
}
return null;
}
}