add a class to a 2d array? Java - java

I need to create a map which has randomly placed trees and food. For the map i am looking to create a 2d array and then add the trees and food to the array with use of classes, is this possible?
class Tree {
char tsymbol;
}
class Food {
char fsymbol;
}
The classes only have to have a symbol stored in them for now, which will be the icon which represents the objects on the map.
public void printWorld (){
int a;
int b;
char[][] map = new char[15][12];
for (a=1; a<=15; ++a)
{
for (b=1; b<=12; ++b)
{
foodsymbol.fsymbol = 1;
final String[] items = { };
map[a][b] =
System.out.print(map[1][1]);
}
System.out.printf("\n\n");
}
}
So far i have this, ignore the comments as that was my previous work. This part is where i am trying to add the objects to the array randomly, however i am having problems accessing the variables or classes in this method.
Thanks in advance for any help:)

Yes, you can have an array of objects, and print them. To have different types of objects in the same array, they should all implement a common interface. For instance:
interface MapObject {
public char getSymbol();
}
class Tree implements MapObject {
char tsymbol = 't';
#override
public char getSymbol() {
return tsymbol;
}
}
class Food implements MapObject {
char fsymbol = 'f';
#override
public char getSymbol() {
return fsymbol;
}
}
class MyClass {
public void printWorld() {
MapObject[][] map = new MapObject[15][12];
map[0][0] = new Tree();
map[0][1] = new Food();
System.out.print(map[0][0].getSymbol());
System.out.print(map[0][1].getSymbol());
}
}

For your particular application, you might also want to consider using an enum. This is useful if all trees are identical and all food is identical. It might look something like this:
enum Item {
TREE ('t'),
FOOD ('f');
private final char symbol;
Item(char symbol) {
this.symbol = symbol;
}
char getSymbol() { return symbol; }
}
class MyClass {
public void printWorld() {
Item[][] map = new Item[15][12];
map[0][0] = Item.TREE;
map[0][1] = Item.FOOD;
System.out.print(map[0][0].getSymbol());
System.out.print(map[0][1].getSymbol());
}
}

Related

TreeSet CompareTo not giving desirable result

I am trying to create a set of all letters in all the words in a dictionary.
I am using a TreeSet for that as I have to do lot's of compare operations.
public class main {
public static void main(String[] args) {
Set<String> lines = new TreeSet<>();
lines.add("ba");
DictAwareSolver myGuesser = new DictAwareSolver(lines);
myGuesser.makeGuess();
}
}
This is my class which is operating on the set
package solver;
import sun.reflect.generics.tree.Tree;
import java.util.*;
import java.lang.System;
public class DictAwareSolver extends HangmanSolver
{
private Set<String> dict;
TreeSet<Node> myTree = new TreeSet<>();
//getters
public Set<String> getDict() {
return dict;
}
// methods
public DictAwareSolver(Set<String> dictionary) {
this.dict = dictionary;
// Implement me!
} // end of DictAwareSolver()
#Override
public void newGame(int[] wordLengths, int maxIncorrectGuesses)
{
// Implement me!
} // end of newGame()
#Override
public char makeGuess() {
Set<String> guessDict = getDict();
Iterator dictItr = guessDict.iterator();
while (dictItr.hasNext())
{
String word = (String) dictItr.next();
for (int i = 0; i<word.length(); i++)
{
Node temp = new Node(word.charAt(i));
myTree.add(temp);
}
}
Iterator treeItr = myTree.iterator();
while (treeItr.hasNext())
{
Node n = (Node) treeItr.next();
System.out.println(n.getLetter() + "-->"+n.getFrequency());
}
// TODO: This is a placeholder, replace with appropriate return value.
return '\0';
} // end of makeGuess()
#Override
public void guessFeedback(char c, Boolean bGuess, ArrayList< ArrayList<Integer> > lPositions)
{
// Implement me!
} // end of guessFeedback()
} // end of class DictAwareSolver
class Node implements Comparable<Node>{
private char letter;
private int frequency;
public Node(char letter)
{
this.letter = letter;
this.frequency = 1;
}
public void countIncrementer()
{
int newCount = getFrequency()+1;
setFrequency(newCount);
}
// getters
public char getLetter() {
return letter;
}
public int getFrequency() {
return frequency;
}
// setters
public void setFrequency(int frequency) {
this.frequency = frequency;
}
#Override
public int compareTo(Node o) {
if (getLetter() == o.letter)
{
o.countIncrementer();
return 0;
}
else if (getLetter() > o.getLetter())
{
return 1;
}
else
{
return -1;
}
}
}
When I am running this whatever I am adding 1st is giving a count of 2. As in this case output is
a-->1
b-->2
but I am expecting
a-->1
b-->1
It will be really helpful if you can point out what is the problem. From what I can think of it should be something in my o.countIncrementer(); in my compareTo method. I am new to java.
The code is making the assumption that the TreeSet will only call the comparator against an equal element if one already exists in the set, and if it does such a comparison, it will only do it exactly once. However, this is not how TreeSet is implemented. Looking at the API documentation for TreeSet, there are no guarantees as to how the comparisons will occur or with what frequency. Since this is not a documented part of the API, the authors of TreeSet are free to implement this functionality in any reasonable manner they wish, so long as it meets the documented API. In fact, they are also allowed to change how it's implemented between versions (e.g. Java 6 & Java 7), or between different implementations (e.g. Oracle vs. IBM).
In short, if the documentation does not guarantee a behavior, your code should not rely on that behavior.
To go into the specific behavior you're seeing, the first element added to a TreeSet (in the versions of Java you're using) is compared against itself. While this is perhaps surprising, it is not disallowed by the API. There may or may not be a good reason for this (I believe the check was added in Java 7 to force a NullPointerException to be thrown when a null is added as the first element to a TreeSet that disallows nulls per this bug). However, in the end, the reason for the check shouldn't matter to users of the API, since it's not disallowed in the API.
public static void main(String[] args) {
System.out.printf("Java vendor & version: %s %s\n", System.getProperty("java.vendor"), Runtime.version());
TreeSet<Character> set = new TreeSet<>(new LoggingComparator<>());
set.add('a');
}
private static class LoggingComparator<T extends Comparable<? super T>> implements Comparator<T> {
#Override
public int compare(T o1, T o2) {
System.out.println(o1 + " <=> " + o2);
return o1.compareTo(o2);
}
}
Java vendor & version: Oracle Corporation 11.0.4+10-LTS
a <=> a

duplicate results with array of array in class

I am new with java and I need to save the content of a stack of objects into an array which will have an array attribute and also the array attribute has an array attribute I know it kind complicated but I need to do that because it's looks like a table. Anyway, this is my code
//First class
public static class classA //inner
{ public char sy;
public ArrayList <Integer> arrystateA;
public classA()
{ sy='0';
arrystateA= new ArrayList <Integer>();} }
//The second class
public static class ArrayofclassA// meddile
{ int num;
public ArrayList <classA> arrystateB;
public ArrayofclassA()
{ arrystateB=new ArrayList < classA>();
num=-1;}
public void creatrans(classA z)
{ arrystateB.add(z);
} }
and this the main code
classA temp2=new classA();
ArrayofclassA temp3 = new ArrayofclassA();
ArrayList<ArrayofclassA> NFAtranstable=new ArrayList<ArrayofclassA>();
while(!reslt.empty()){
temp=reslt.pop();
for (int i=0;i<NFAtranstable.size();i++)
{temp3=NFAtranstable.get(i);
if (temp3.num==temp.s_to)
{
if(temp3.arrystateB.get(i).sy==temp.t_sym)
{
temp3.arrystateB.get(i).arrystateA.add(temp.s_to);
match=true;
}else
{temp2.sy=temp.t_sym;temp2.arrystateA.add(temp.s_to);
temp3.creatrans(temp2);
match=true;
}
}
}
if(!match)
{
temp2.sy=temp.t_sym;
temp2.arrystateA.add(temp.s_to);
temp3.num=temp.s_from;
temp3.arrystateB.add(temp2);
NFAtranstable.add(temp3);
}
match=false;
}
for(int i=0;i<NFAtranstable.size();i++)
{
System.out.print(NFAtranstable.get(i).num+" ");
for(int j=0;j<NFAtranstable.get(i).arrystateB.size();j++)
{
System.out.println(NFAtranstable.get(i).arrystateB.get(j).sy+" ");
for(int k=0;k<NFAtranstable.get(i).arrystateB.get(j).arrystateA.size();k++)
{
System.out.print(NFAtranstable.get(i).arrystateB.get(j).arrystateA.get(k));
}
}
}
}
the problem that when I print the content of the array 'NFAtranstable' it's gives me duplicate results like it just save the same valus, it's been about 8 hours and I couldn't find the problem =(

Generalized List as a parameter for a method

Say I have a simple class like this:
public class BasicObject {
private String name;
public BasicObject (String str) {
name = str;
}
public String getName () {
return name;
}
}
then I have some simple method in the main class like this:
private static int findInList (____ list, String str) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getName().equalsIgnoreCase(str)) {
return i;
}
}
return -1;
}
It would work if I put List<BasicObject> on the blank for the parameter list, but what if I have other objects? Can I generalize the list so this would work with other objects besides BasicObject? If so, how can I get the type of the objects in the list?
Edit: What if I have another class from an imported package that I can still put in a list but I don't want to change what it implements? Is there a way to have a generalized findInList that includes those too? Or do I have to just make another method for that? I'm fine with just making another method, but I'm curious if this way is possible.
You can use an interface structure such as this
Doing so provides a common call structure, so it is predictable what can be called from the implementations
public interface IShape {
String getName();
}
public class Square implements IShape {
private String name = "Square";
#Override
public String getName() {
return name;
}
}
public class Circle implements IShape {
private String name = "Circle";
#Override
public String getName() {
return name;
}
}
public static void main(String[] args){
List<IShape> list = new ArrayList<>();
list.add(new Square());
list.add(new Circle());
list.add(new Circle());
list.add(new Square());
list.add(new IShape() {
#Override
public String getName() {
return "Triangle";
}
});
for(IShape test : list){
System.out.println(test.getName());
}
}
this produces an output like this
Square
Circle
Circle
Square
Triangle
as answer to edit
Yes, but requires reflection, if help is needed on this, please open a new question after proberly trying to solve the issue yourself.
Have you tried checking generics? It is what you're looking for, your method signature should look like below:
public <T> List<T> findInList (Class<T> list, String str) {}
This will work if all objects have common parent (BasicObject or any other class which have getName() method).
private static int findInList (List<? extends BasicObject> list, String str) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getName().equalsIgnoreCase(str)) {
return i;
}
}
return -1;
}
Your code relies on the list having an element type with a getName method that is visible to the compiler. Another way is to use lambdas. For example,
public interface Named {
String getName();
}
public class UseNamed<T extends Named> {
public int findIndex(List<T> nameds, String search) {
for (int len = nameds.size(), ix = 0; ix < len; ++ix) {
final Named named = names.get(ix);
if (search.equalsIgnoreCase(named.getName())) {
return ix;
}
}
return -1;
}
One approach with lambdas is to pass a comparer to findIndex:
public <T, K> int findIndex(List<T> stuff, K search,
BiFunction<T, K, Boolean> compares) {...}
and call it with
List<Named> stuff = ...;
String search = ...;
int index = findIndex(stuff, search,
(named, s) -> s.equalsIgnoreCase(named.getName()));

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.

implementing and interfaces

I tried looking up tutorials and videos and I understand what implementing does, although I'm a bit confused as to how one would implement a class from the Java Library. In my homework, I'm suppose to utilize the class, DataSet and make it so it accepts Comparable objects. The program is suppose to record the Min and Max values depending on the objects, in this case, I'm suppose to use strings. I wasn't sure if I needed any classes to implement the Comparable interface, so I made two classes just in case I was suppose to do so. My real question is how do I actually incorperate a String variable in the tester class to actually read and compare the object to another? thanks in advance.
public class Word implements Comparable
{
private String str;
public Word()
{
str = null;
}
public Word(String s)
{
str = s;
}
public int compareTo(Object other)
{
String n = (String) other;
return str.compareTo(n);
}
}
I wasn't sure which of the two classes would be suitable for implementing Although i think the String class below would not work at all b/c It's already a standard class so I wasn't too sure about using it
public class String implements Comparable
{
public String s;
public String()
{
s = null;
}
public String(String str)
{
s = str;
}
public int compareTo(Object other)
{
String n = (String) other;
return s.compareTo(n);
}
}
public interface Comparable
{
public int compareTo(Object other);
}
public class DataSet
{
private Object maximum;
private Object least;
private Comparable compare;
private int count;
public DataSet(Comparable s)
{
compare = s;
}
public void add(Object x)
{
if(count == 0)
least = x;
if(count == 0 || compare.compareTo(x) >=0)
maximum = x;
else if(compare.compareTo(x) <0)
least = x;
count++;
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
public class DataSetTester
{
public static void main(String[] args)
{
Comparable n = new Word("sand");
DataSet data = new DataSet(n);
data.add(new Word(man));
System.out.println("Maximum Word: " + data.getMaximum());
System.out.println("Least Word: " + data.getLeast());
}
}
An interface is a contract that showes that your class contain all methodes that are implemented in the interface. In this case the CompareTo(object other). The String class already implements the comparable interface so you don't need youre own class. I think your data set class should look something like this :
public class DataSet<T implements Comparable>
{
private T maximum;
private T least;
private T count;
public void add(T x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public T getMaximum()
{
return maximum;
}
public T getLeast()
{
return least;
}
}
T is a generic type and in your case it should be String, Here is how you create a new Data set:
DataSet<String> ds = new DataSet<String>;

Categories