i started learning a bit more about Java and got stuck here :
Wanted to make Objects that contain value, index and a rest and in main method a list of objects.
By adding new objects to the list the previous entry gets overwritten.
Here is my code so far :
public class LNGHW {
public static int value;
public static int index;
public static int rest;
public LNGHW(int val, int index, int mod) {
this.value = val;
this.index = index;
this.rest = mod;
}
public static void main(String[] args) {
ArrayList<LNGHW> items = new ArrayList<LNGHW>();
items.add(new LNGHW(4, 0, 1));
items.add(new LNGHW(2, 1, 1));
System.out.println(items.get(0).getValue());
System.out.println(items.get(1).getValue());
}
public int getValue() {
return value;
}
public static void setValue(int value) {
LNGHW.value = value;
}
public static int getIndex() {
return index;
}
public static void setIndex(int index) {
LNGHW.index = index;
}
public static int getRest() {
return rest;
}
public static void setRest(int rest) {
LNGHW.rest = rest;
}
}
I am open for every kind of help!
import java.util.*;
import java.lang.*;
import java.io.*;
class LNGHW {
public int value; /*made them non-static*/
public int index;
public int rest;
public LNGHW(int val, int index, int mod) {
this.value = val;
this.index = index;
this.rest = mod;
}
public static void main(String[] args) {
ArrayList<LNGHW> items = new ArrayList<LNGHW>();
items.add(new LNGHW(4, 0, 1));
items.add(new LNGHW(2, 1, 1));
System.out.println(items.get(0).getValue());
System.out.println(items.get(1).getValue());
}
public int getValue() {
return this.value;
}
public void setValue(int value) { /*made these values non-static*/
this.value = value; /*set the values of object using **this**,not class name */
}
public int getIndex() {
return this.index;
}
public void setIndex(int index) {
this.index = index;
}
public int getRest() {
return this.rest;
}
public void setRest(int rest) {
this.rest = rest;
}}
To understand why it was happening you need to understand about static,non-static and this keyword in java. Please study about them and then you can understand the difference.
STATIC--when we want any property to be same for every object of a class then we use static keyword. For eg- suppose there is a MAN class and there are few attributes such as age,gender etc, then age will be different for different objects of man class i.e. age attribute is a object level property hence it will be non-static. whereas gender of every object of the MAN class will be male,hence it is a class level property and therefore it should be static.
Finally whenever there is a class level property we use static variables otherwise for object level property we use non-static variables.
we use this keyword to refer non-static variables where as class name for referring static variables.
Related
As I'm going though the debugger it looks like it is working at first, however when I try calling getCoordinates() in my shipSunk() method, it returns a null value almost every time. What is wrong here?
public boolean shipSunk(ShipDerived[] s){
ArrayListMultimap<Integer, Integer> temp;
ArrayList<Integer> temp2 = new ArrayList<>();
boolean sunk = false;
for(int i=s.length-1; i>=0;i--){
Ship st = s[i];
temp = s[i].getCoordinates(); //returns null almost every time???
temp2 = s[i].getCoordinatesList();
for (Map.Entry<Integer, Integer> entry : temp.entries()){
//System.out.println(entry.getKey() + ", " + entry.getValue());
if(grid[entry.getKey()][entry.getValue()]=='x'){
sunk = true;
}
else{
sunk = false;
}
}
if(sunk==true){
System.out.println("Ship has been sunk!");
}
temp.clear();
}
return sunk;
}
And here is my Ship class (extended from abstract class) methods:
import java.util.ArrayList;
public class ShipDerived extends Ship{
private String type;
private int length;
private ArrayListMultimap<Integer, Integer> coordinates = ArrayListMultimap.create();
private ArrayList<Integer> c2 = new ArrayList<>();
public ShipDerived(){
this.type = type;
this.length = length;
this.coordinates = getCoordinates();
this.c2 = getCoordinatesList();
}
public ShipDerived(String t, int l){
this.type = t;
this.length = l;
this.coordinates = getCoordinates();
this.c2 = getCoordinatesList();
}
#Override
void setType(String t) {
type = t;
}
#Override
void setLength(int l) {
length = l;
}
#Override
String getType() {
return type;
}
#Override
int getLength() {
return length;
}
#Override
ArrayListMultimap<Integer, Integer> getCoordinates() {
return this.coordinates;
}
ArrayList<Integer> getCoordinatesList() {
return this.c2;
}
#Override
void setCoordinates(int i, int j) {
//coordinates.putAll(i, Collections.singleton(j));
this.coordinates.put(i,j);
this.c2.add(i);
this.c2.add(j);
}
}
Here is my Ship (abstract) class:
public abstract class Ship {
private int length;
private String type;
private ArrayListMultimap<Integer, Integer> coordinates;
Ship(){
this.length = length;
this.type = type;
}
abstract void setType(String t);
abstract void setLength(int l);
abstract String getType();
abstract int getLength();
abstract ArrayListMultimap<Integer, Integer> getCoordinates();
abstract void setCoordinates(int i, int j);
}
And this is what I am passing into my shipSunk() method. I an using getters/setters to create my ships:
p1board.shipSunk(p1.getShips()); //player 1
p2board.shipSunk(p2.getShips()); //player 2
These seem to work but here's some code into these as well:
public class Player {
private String name;
private ShipDerived[] ships = new ShipDerived[5];
public Player(){
this.name = name;
this.ships = ships;
}
public String getName(){
return name;
}
public void setName(String x){
name = x;
}
public void setShips(){
int a = 0;
for(int i=5; i>=1;i--){
ShipDerived s = new ShipDerived("null", 0);
Array.set(ships, a, s);
a++;
}
ships[0].setType("carrier");
ships[0].setLength(5);
ships[1].setType("battleship");
ships[1].setLength(4);
ships[2].setType("destroyer");
ships[2].setLength(3);
ships[3].setType("submarine");
ships[3].setLength(3);
ships[4].setType("patrol boat");
ships[4].setLength(2);
}
public ShipDerived[] getShips(){
return ships;
}
You initialize this.coordinates twice. First as an inline field initializer and second in the constructor. The statement this.coordinates = getCoordinates(); does not make sense because the getter returns this.coordinates, so you effectively get this.coordinates = this.coordinates;
This shouldn't effect your issue, but my recommendation for easier debugging is to just set all fields that you can to final to avoid issues such as this and remove the superfluous call from the constructor.
Then I would investigate the ArrayListMultimap.create(); method, if there is any way that one returns null.
You have #Override annotation on getCoordinates() so I'm guessing your Ship class also have coordinates field. In shipSunk method you cast your object to Ship class so most likely it operate on field Ship.coordintes whis is null because you are initializing only DerivedShip.coordinates.
Check this for simple example of hiding fields: If you overwrite a field in a subclass of a class, the subclass has two fields with the same name(and different type)?
There are so many strange things in your code:
Why has the Ship class private fields if you don't provide access methods for those fields? Without accessor methods nobody can use those fields, so just delete them!
Why do the ShipDerived constructors initialize the coordinates and c2 fields if you already initialize them at the declaration?
Why does Player.setShips() use some obscure Array.set(ships, a, s); when ships[a] = s; would be sufficient?
Why do your constructors (for Ship, ShipDerived and Player) contain nonsense-code like this.type = type; (in ShipDeriveds default constructor) that seems important but does nothing?
Why does the Player.setShips() method create empty ShipDerived instances and only afterwards sets their values?
After some cleanup your classes could look like:
Ship.java:
import com.google.common.collect.ArrayListMultimap;
public abstract class Ship {
Ship(){
}
abstract void setType(String t);
abstract void setLength(int l);
abstract String getType();
abstract int getLength();
abstract ArrayListMultimap<Integer, Integer> getCoordinates();
abstract void setCoordinates(int i, int j);
}
ShipDerived.java:
import java.util.ArrayList;
import com.google.common.collect.ArrayListMultimap;
public class ShipDerived extends Ship{
private String type;
private int length;
private ArrayListMultimap<Integer, Integer> coordinates = ArrayListMultimap.create();
private ArrayList<Integer> c2 = new ArrayList<>();
public ShipDerived(){
}
public ShipDerived(String t, int l){
this.type = t;
this.length = l;
}
#Override
void setType(String t) {
type = t;
}
#Override
void setLength(int l) {
length = l;
}
#Override
String getType() {
return type;
}
#Override
int getLength() {
return length;
}
#Override
ArrayListMultimap<Integer, Integer> getCoordinates() {
return this.coordinates;
}
ArrayList<Integer> getCoordinatesList() {
return this.c2;
}
#Override
void setCoordinates(int i, int j) {
this.coordinates.put(i, j);
this.c2.add(i);
this.c2.add(j);
}
}
Player.java:
public class Player {
private String name;
private ShipDerived[] ships = new ShipDerived[5];
public Player(){
}
public String getName(){
return name;
}
public void setName(String x){
name = x;
}
public void setShips(){
ships[0] = new ShipDerived("carrier", 5);
ships[1] = new ShipDerived("battleship", 4);
ships[2] = new ShipDerived("destroyer", 3);
ships[3] = new ShipDerived("submarine", 3);
ships[4] = new ShipDerived("patrol boat", 2);
}
public ShipDerived[] getShips(){
return ships;
}
}
These changes might not yet solve your issue, but at least make your code easier to read and understand.
Actually, since the Ship class no longer contains any fields and has only abstract methods you could even turn it into an interface (but that would mean that your methods are now public instead of package private, which would mean that you would also need to declare them as public in ShipDerived).
Ship.java, interface version:
import com.google.common.collect.ArrayListMultimap;
public interface Ship {
void setType(String t);
void setLength(int l);
String getType();
int getLength();
ArrayListMultimap<Integer, Integer> getCoordinates();
void setCoordinates(int i, int j);
}
I'm doing an assignment in which I have created an Appliance class that has a timePasses()method within it. This method re-directs some values that need to be stored within another method that is inside of another class. Here is where I am up to on this:
Appliance
public class ElectricCooker extends Cooker {
public int isOn = -1;
public int isOff = 0;
public int incrementTime;
public int varPass = -1;
#Override
public int currentState() {
if (varPass == 0) {
return isOff;
} else {
return isOn;
}
}
#Override
public void useTime(int defaultTime) {
defaultTime = 15;
incrementTime = 4;
}
#Override
public void timePasses() {
if (varPass == isOff) {
varPass = 0;
} else {
ElectricMeter.getInstance().incrementConsumed(electricityUse);
GasMeter.getInstance().incrementConsumed(gasUse);
WaterMeter.getInstance().incrementConsumed(waterUse);
}
}
ElectricCooker(int electricityUse, int gasUse, int waterUse, int timeOn) {
super(electricityUse, gasUse, waterUse, timeOn);
this.electricityUse = 5 * incrementTime;
this.gasUse = 0 * incrementTime;
this.waterUse = 0 * incrementTime;
this.timeOn = 15 * incrementTime;
}
}
Meter
public class ElectricMeter {
ElectricMeter() {
}
private static ElectricMeter instance = new ElectricMeter();
public static ElectricMeter getInstance() {
return instance;
}
public void incrementConsumed(int value) {
System.out.println(value);
}
public int incrementGenerated() {
}
public boolean canGenerate() {
}
public String getConsumed() {
}
public String getGenerated() {
}
}
Main method
public class MainCoursework {
public static void main(String[] args) {
ElectricMeter a = new ElectricMeter();
a.incrementConsumed(//what goes here?);
}
}
So the value from timePasses()has been redirected into an ElectricMeter instance but now I need to return that value to the increentConsumed() method in the meter class and I'm stuck on how to do this. Since the value of electricityConsumed is 20, the output should be 20. But instead I have to pass a parameter into a.incrementConsumed(//pass parameter here) and what ever is passed gets printed out onto the screen instead of the 20 from electrictyUse. Any help on how to do this is appreciated, thanks.
Actually, the incrementConsumed method is indeed implemented as you described:
public void incrementConsumed(int value)
{
System.out.println(value);
}
A method called incrementXXX shouldn't really output anything, should it? It should increment a variable/field:
private int electricityUsed = 0;
public void incrementConsumed(int value)
{
electricityUsed += value;
}
You should declare another method that returns electricityUsed:
public int getElectricityUsed() {
return electricityUsed;
}
Now let's fix your main method.
In your main method, you didn't even create anything that consumes electricity! How can the electric meter incrementConsumed? So remove everything from the main method and create a cooker:
// your constructor looks weird. So I passed in some random arguments..
ElectricCooker cooker = new ElectricCooker(20, 0, 0, 60);
Now call timePasses to simulate that some time passed:
cooker.timePasses();
And print the electricity used:
System.out.println(ElectricMeter.getInstance().getElectricityUsed());
you need to create an instance variable in ElectricMeter and update that value on say incrementConsumed. When you want to print that use accessor of this variable.
public class Electric {
public static void main(String[] args) {
ElectricCooker cooker = new ElectricCooker(1,2,3,4);
//opertion on cooker
//ignoring best way for singleton creation
int electricityUse = ElectricMeter.getInstance().getElectricityUse();
System.out.println(electricityUse);
}
}
class ElectricCooker // extends Cooker
{
public int isOn = -1;
public int isOff = 0;
public int incrementTime;
public int varPass = -1;
public int electricityUse = -1;
public int currentState() {
if (varPass == 0)
return isOff;
else {
return isOn;
}
}
public void useTime(int defaultTime) {
defaultTime = 15;
incrementTime = 4;
}
public void timePasses() {
if (varPass == isOff)
varPass = 0;
else {
ElectricMeter.getInstance().incrementConsumed(electricityUse);
}
}
ElectricCooker(int electricityUse, int gasUse, int waterUse, int timeOn) {
this.electricityUse = 5 * incrementTime;
}
}
class ElectricMeter {
public int electricityUse = -1;
private static ElectricMeter instance = new ElectricMeter();
public static ElectricMeter getInstance() {
return instance;
}
public void incrementConsumed(int value) {
this.electricityUse = value;
}
public int getElectricityUse() {
return electricityUse;
}
}
In ElectricMeter, some operations don't perform what they should.
ElectricMeter.getInstance().incrementConsumed(electricityUse);
should increment something but it writes only in the output:
public void incrementConsumed(int value){
System.out.println(value);
}
You should write it rather :
public void incrementConsumed(int value){
consumed+=value;
}
and add a private int consumed field in ElectricMeter class to store the actual consumed.
And your getConsumed() which has a empty implementation :
public String getConsumed(){
}
should simply return the consumed field and you should return a int value and not a String.
public int getConsumed() {
return consumed;
}
In this way, you can do :
public static void main(String[] args){
ElectricMeter.getInstance().incrementConsumed(20);
int consumed = ElectricMeter.getInstance().getConsumed();
}
I have started experimenting with the Jenetics library, however I am having some issues with trying to make a very easy "custom" set of gene/chromosomes.
What I tried to do was to create a custom chromosome with a different (random) number of custom genes inside. The genes simply contain an integer value, just for the sake of simplicity. For the same simplicity, the contents of a gene can only be numbers ranging from 0 to 9 and a Gene is considered valid only if it does NOT contain the number 9 (again, retardedly simple, but I just wanted to make them custom)
Here is my code:
CustomGene:
public class CustomGene implements Gene<Integer, CustomGene> {
private Integer value;
private CustomGene(Integer value) {
this.value = value;
}
public static CustomGene of(Integer value) {
return new CustomGene(value);
}
public static ISeq<CustomGene> seq(Integer min, Integer max, int length) {
Random r = RandomRegistry.getRandom();
return MSeq.<CustomGene>ofLength(length).fill(() ->
new CustomGene(random.nextInt(r, min, max))
).toISeq();
}
#Override
public Integer getAllele() {
return value;
}
#Override
public CustomGene newInstance() {
final Random random = RandomRegistry.getRandom();
return new CustomGene(Math.abs(random.nextInt(9)));
}
#Override
public CustomGene newInstance(Integer integer) {
return new CustomGene(integer);
}
#Override
public boolean isValid() {
return value != 9;
}
}
CustomChromosome:
import org.jenetics.Chromosome;
import org.jenetics.util.ISeq;
import org.jenetics.util.RandomRegistry;
import java.util.Iterator;
import java.util.Random;
public class CustomChromosome implements Chromosome<CustomGene> {
private ISeq<CustomGene> iSeq;
private final int length;
public CustomChromosome(ISeq<CustomGene> genes) {
this.iSeq = genes;
this.length = iSeq.length();
}
public static CustomChromosome of(ISeq<CustomGene> genes) {
return new CustomChromosome(genes);
}
#Override
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) {
this.iSeq = iSeq;
return this;
}
#Override
public CustomGene getGene(int i) {
return iSeq.get(i);
}
#Override
public int length() {
return iSeq.length();
}
#Override
public ISeq<CustomGene> toSeq() {
return iSeq;
}
#Override
public Chromosome<CustomGene> newInstance() {
final Random random = RandomRegistry.getRandom();
ISeq<CustomGene> genes = ISeq.empty();
for (int i = 0; i < length; i++) {
genes = genes.append(CustomGene.of(Math.abs(random.nextInt(9))));
}
return new CustomChromosome(genes);
}
#Override
public Iterator<CustomGene> iterator() {
return iSeq.iterator();
}
#Override
public boolean isValid() {
return iSeq.stream().allMatch(CustomGene::isValid);
}
}
Main:
import org.jenetics.Genotype;
import org.jenetics.Optimize;
import org.jenetics.engine.Engine;
import org.jenetics.engine.EvolutionResult;
import org.jenetics.util.Factory;
import org.jenetics.util.RandomRegistry;
import java.util.Random;
public class Main {
private static int maxSum = - 100;
private static Integer eval(Genotype<CustomGene> gt) {
final int sum = gt.getChromosome().stream().mapToInt(CustomGene::getAllele).sum();
if(sum > maxSum)
maxSum = sum;
return sum;
}
public static void main(String[] args) {
final Random random = RandomRegistry.getRandom();
Factory<Genotype<CustomGene>> g =
Genotype.of(CustomChromosome.of(CustomGene.seq(0, 9, Math.abs(random.nextInt(9)) + 1)));
Engine<CustomGene, Integer> engine = Engine
.builder(Main::eval, g)
.optimize(Optimize.MAXIMUM)
.populationSize(100)
.build();
Genotype<CustomGene> result = engine.stream().limit(10000)
.collect(EvolutionResult.toBestGenotype());
System.out.println(eval(result));
result.getChromosome().stream().forEach(i -> {
System.out.print(i.getAllele() + " ");
});
System.out.println();
System.out.println(maxSum);
}
}
I do not understand why I get this output:
13 (evaluated result)
1 8 0 4 (all the alleles form the genes of the chosen chromosome)
32 (the actual maximum fitness found)
We can clearly see a difference between the genotype which had the biggest fitness function and the chosen genotype. Why?
I know I'm doing something wrong and it's probably a silly mistake, but I really can't seem to understand what I am doing wrong. Could you please help me out?
Lots of thanks!
As posted by the creator of the library here, the answer was:
you violated the contract of the Chromosome.newInstance(ISeq) method. This method must return a new chromosome instance. After fixing this
#Override
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) {
return new CustomChromosome(iSeq);
}
Suppose I am importing table entries, where a single entry can be stored in a class:
class Foo {
int i1;
int i2;
double d1;
}
After the import is complete, I will need to have access to the imported values themselves, as well as to their normalized versions. So far, I have implemented this functionality as follows:
class FooWithMaxTracking {
private int i1;
private static int i1_max=0;
public void setI1(int value){
this.i1 = value;
if (value > i1_max) { i1_max = value; }}
public int getI1(){
return i1;}
public double normI1(){
return i1/((double)i1_max);}
private int i2;
private static int i2_max=0;
public void setI2(int value){ <code identical to written above> }
public int getI2(){ ... }
public double normI2(){ ... }
// and another set of similar 2 variables & 3 functions for 'double d1'
}
In this implementation I strongly dislike the fact that I had to write the same code many times (only three in this example, but about ten times in the real project). Is there any way to make the code more DRY ("don't repeat yourself")?
If you do not mind a slight loss of performance, you can put all the maxima in a static Map, define a class that holds a getter, a setter, and a norm methods, and replace the individual variables with instances of that class:
private static Map<String,Object> max = new HashMap<String,Object>();
private static class IntMaxTrack {
private final String key;
private int value;
public IntMaxTrack(String k, int v) {
key = k;
value = v;
max.put(key, value);
}
public int get() { return value; }
public void set(int v) {
int m = ((Integer)max.get(key)).intValue();
value = v;
if (value > m) {
max.put(key, value);
}
}
public double norm() {
int m = ((Integer)max.get(key)).intValue();
return val / ((double)m);
}
}
Make a similar class for double, i.e. DblMaxTrack Now you can replace primitives with instances of these classes, and call their get, set, and norm from the corresponding methods of your class.
What about defining one class with the necessary code, like:
public class Bar {
private int i1;
private static int i1_max = 0;
public void setI1(int value) {
// ...
}
public int getI1() {
// ...
}
public double normI1() {
// ...
}
}
And using it sevearl times, like:
class FooWithMaxTracking {
one = new Bar();
two = new Bar();
three = new BarForDouble();
}
Suppose I have a Enum defined something like this:
public enum Sample{
// suppose AClass.getValue() returns an int
A(AClass.getValue()),
B(AClass.getValue()),
C(AClass.getValue());
private int _value;
private Sample(int _val){
this._value = _val;
}
public int getVal(){
return _value;
}
I can pull out values using Sample.A or Sample.A.getAVal() without issue.
Now suppose that AClass.getValue() could take a parameter to return a possibly different particular value, eg AClass.getValue(42).
It is possible to pass arguments to a public Enum method and retrive the Enum values? In other words, could I have an Enum definition like
public enum Sample{
// suppose AClass.getValue() returns an int
A(AClass.getAValue()),
B(AClass.getBValue()),
C(AClass.getCValue());
private int _value;
private Sample(int _val){
this._value = _val;
}
public int getVal(){
return _value;
}
public int getVal(int a){
// somehow pull out AClass.getAValue(a)
}
using Sample.A.getValue(42)?
You can do it, but only by making an abstract method in the enum, and overriding it in each value:
public enum Sample {
A(AClass.getAValue()) {
#Override public int getVal(int x) {
return AClass.getAValue(x);
}
},
B(BClass.getAValue()) {
#Override public int getVal(int x) {
return BClass.getBValue(x);
}
},
C(CClass.getAValue()) {
#Override public int getVal(int x) {
return CClass.getCValue(x);
}
};
private int _value;
private Sample(int _val){
this._value = _val;
}
public int getVal(){
return _value;
}
public abstract int getVal(int x);
}
Of course if you could create an instance of some other base type which has a getValue(int x) method, then you could put the code into the enum class itself instead of into the nested ones.
As stated in Java Specification
there is only one instance of each enum constant
So no, you can't have different values of a specific enum constant.
But you could put an array or a map inside your enum, so Sample.A.getValue(42) would return Sample.A.myMap.get(42) :
public enum Sample{
A(),
B(),
C();
Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();
public int getVal(int i){
return myMap.get(i);
}
public int setVal(int i, int v){
return myMap.put(i, v);
}
}
public class App {
public static void main(String[] args) {
Fruit.setCounter(5);
System.out.println(Fruit.Apple.getCmd());
Fruit.setCounter(6);
System.out.println(Fruit.Apple.getCmd());
}
}
public enum Fruit {
Apple {
public String getCmd() {
return counter + " apples";
}
},
Banana {
public String getCmd() {
return counter + " bananas";
}
};
private static int counter = 0;
public abstract String getCmd();
public static void setCounter(int c) {
counter = c;
}
}
Output:
5 apples
6 apples