I have a class making operations on a chess board. Every cell has its states. The board is an array whose declaration is:
private CellState[][] cellBoard = new CellState[8][8];
I have many methods that have 3 arguments: row (horizontal), file (vertical) and state. They traverse board cell by cell. To refactor repeating code, I wrote the following method:
private void traverseBoard(Command method) {
for(int row = 0; row < 8; row++) {
for(int file = 0; file < 8; file++) {
method.execute(row, file, cellBoard[row][file]);
}
}
}
protected interface Command {
public void execute(int x, int y, CELL_STATE state);
}
In one of the methods, I check if every cell is empty:
private boolean areAllEmpty() {
ExtendedBoolean empty = new ExtendedBoolean(true);
traverseBoard((i, j, state) -> {
if (state != CELL_STATE.EMPTY) {
empty.set(false);
}
});
return empty.is();
}
I could not use the primitive boolean, because it is immutable. For that purpose, I created a nested class:
private class ExtendedBoolean {
boolean bool;
public ExtendedBoolean(boolean bool) {
this.bool = bool;
}
public void set(boolean bool) {
this.bool = bool;
}
public boolean is() {
return bool;
}
}
I hope there is a better way of passing a method with multiple arguments inside a lambda expression. I am aware it is possible to use Runnable like in this answer. However, in that case I cannot pass any parameter.
I hope that I don't have to write ExtendedBoolean, whose only purpose is to wrap a primitive. I had to write ExtendedInteger as well.
Are my hopes reasonable?
EDIT: The collection of cell states has to be mutable. I change states of cells and then check them. I do it in a loop until condition is fulfilled.
You could use a Stream to represent your board, and thus benefit of all the Stream methods:
Stream<Cell> stream =
IntStream.range(0, 64)
.mapToObj(i -> {
int row = i / 8;
int column = i % 8;
return new Cell(row, column, cellBoard[row][column]);
});
where the Cell class would be defined as
private static class Cell {
private final int row;
private final int column;
private final CELL_STATE state;
public Cell(int row, int column, CELL_STATE state) {
this.row = row;
this.column = column;
this.state = state;
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
public CELL_STATE getState() {
return state;
}
#Override
public String toString() {
return "Cell{" +
"row=" + row +
", column=" + column +
", state=" + state +
'}';
}
}
Now, to implement your usecase, all you would have to do would be
stream.allMatch(cell -> cell.getState() == CELL_STATE.EMPTY);
You can try to combine generics and lambdas together with something like this:
protected interface Command<T> {
public T execute(T prev, int x, int y, CELL_STATE state);
}
private <T> T traverseBoard(T initial, Command<T> method) {
T result = initial;
for(int row = 0; row < 8; row++) {
for(int file = 0; file < 8; file++) {
result = method.execute( result, row, file, null );
}
}
return result;
}
private boolean areAllEmpty() {
return traverseBoard( Boolean.FALSE, (b, i, j, state) -> {
if ( state != CELL_STATE.EMPTY ) {
return false;
}else{
return true;
}
} );
}
private int count() {
return traverseBoard( 0, (c, i, j, state) -> c += 1 );
}
I also throw in an example of how you can do count in order to see how state is maintained.
But I like #JB Nizet answer using streams.
One easy way is to write your own simple generic Mutable:
public class Mutable<T> {
T it;
public Mutable(T it) {
this.it = it;
}
public void set(T it) {
this.it = it;
}
public T get() {
return it;
}
}
You can then use a Mutable<Boolean> in your case and rely on autoboxing to make it handle boolean.
In lambdas all variables that are captured from the outside scope (clojure) need to be final, or effectively final, and thats why it does not let you directly change a variable, if Javas Implementation for clojures were like those of C# or JavaScript you would not need to use this.
A pattern used in Java is to declare an array with only 1 element in this case array with one boolean and then change the content of the array (i think it is ugly).
boolean[] empty = new boolean[]{false};
traverseBoard((i,j,state) -> empty[0] = true ) // Simple usage
I think this solution (my opinion) is ugly, another one is to create an Holder class, that is Generic, so whenever you need something similar you could used it.
As an example:
Holder<Student> studentHolder = new Holder<>(student);
doSomething( anotherStudent -> studentHolder.value = anotherStudent );
With this last approach be sure to create default ones for primitive types, so there is no Boxing/Unboxing overhead.
BooleanHolder boolHolder = new BooleanHolder(false);
Your traverseBoard method is correct if all you want to do is take some action for each cell. However, if you need to check some condition on each cell, you need another approach.
As I see it, the problem is that you need to design a method that traverses your board and returns a boolean instead of void. Here's something to start with:
private boolean allCellsInBoardMatch(Condition condition) {
for (int row = 0; row < 8; row++) {
for (int file = 0; file < 8; file++) {
if (!condition.check(row, file, cellBoard[row][file])) {
return false;
}
}
}
return true;
}
protected interface Condition {
boolean check(int x, int y, CELL_STATE state);
}
This approach, besides working as expected without needing a wrapper type, is more efficient, because it stops iterating as soon as the condition is not met for a cell, while the approach you were using was traversing the whole board.
Your example that checks if all the cells are empty could now be rewritten as follows:
private boolean areAllEmpty() {
return allCellsInBoardMatch((i, j, state) -> state == CELL_STATE.EMPTY);
}
Related
I am using an ArrayList to store objects that are "valid" for the purposes of my program and referencing it later in the same class file.
private static ArrayList<TownResource> validResources = new ArrayList<>();
A public method is called, which then calls a private method within the class that makes validResources's size nonzero.
public static boolean detection(int row, int col, TownResource[][] rArray, ResourceEnum[][][] bT, BuildingEnum buildingType) {
int checkTime = 0;
int patternIndex = 0;
try {
for (int i = 1; i < checkTime+1; i++) {
if (compare(row, col, rArray, buildingTemplate[patternIndex], buildingType)) {
for (int j = 0; j < validResources.size(); j++) {
validResources.get(j).setScannedBuilding(buildingType);
}
System.out.println("Size at compare" + validResources.size());
return true;
}
}
}
catch (ArrayIndexOutOfBoundsException e){
//System.out.println("Out of bounds exception?");
}
return false;
}
The compare method is a private method that on one condition, may clear validResources.
private static boolean compare(int row, int col, TownResource[][] rArray, ResourceEnum[][] buildingTemplate, BuildingEnum buildingType) {
for (int r = 0; r < buildingTemplate.length; r++) {
for (int c = 0; c < buildingTemplate[r].length; c++) {
if (match(rArray[row+r][col+c], buildingTemplate[r][c])) {
//System.out.println("Successful comparison at " + (row+r) + ", " + (col+c));
}
else {
validResources.clear();
return false;
}
}
}
return true;
}
match is what sets validResources to be nonzero in size:
private static boolean match(TownResource toBeChecked, ResourceEnum checker) {
if (checker == ResourceEnum.NONE) {
return true;
}
else if (toBeChecked.getResource() == checker) {
validResources.add(toBeChecked);
return true;
}
return false;
}
However, when I know validResources to be nonzero in size(this causes detection to return true which triggers a new method placement), it becomes zero.
public static void placement(TownResource[][] rArray, Building[][] bArray, BuildingEnum building) {
// other parts of method commented out for example
System.out.println(validResources.size());
for (int i = 0; i < validResources.size(); i++) {
System.out.println("Is this statement firing?");
System.out.println(validResources.get(i).getResource());
validResources.get(i).setResource(ResourceEnum.NONE);
}
Have I declared validResources incorrectly? Or is there something else at play?
Thank you.
This was an error in how I executed detection(). This method is called by another method within another class when iterating through a 2D array. The ArrayList validResources becomes nonempty in one check, but gets overwritten by another as a result of the program not calling placement until every object in the 2D array had detection called on it. I changed this to call placement immediately.
I just came to the problem where I want to call a function of an Object inside a HashMap. I already searched it up and found one thread but sadly I don't understand it.
So here's my code
public class Seat {
//some attributes
public int getNumber() {
return number;
}
public boolean isReserved() {
return status;
}
}
public class Hall {
private HashMap mySeats;
public HashMap getMeinePlaetze() {
return meinePlaetze;
}
public void createSeats() {
for (int i = 1; i <= this.getnumberOfSeats(); i++) {
this.getMySeats().put(i, new Seat(i, 1));
}
}
}
public class Main {
Hall h1 = new Hall(...);
h1.createSeats();
h1.getMySeats().get(2).isReserved(); //How do I have to write this to work out?
}
I hope my intend is reasonable. Feel free to correct me if my code sucks. I already apologize for it.
Thank you very much.
Since version 5, Java has a feature called Generics. You'll find a lot about generics on the web, from articles, blog posts, etc to very good answers here on StackOverflow.
Generics allows Java to be a strongly typed language. This means that variables in Java can not only be declared to be of some type (i.e. HashMap), but also to be of some type along with one or more generic type parameters (i.e. HashMap<K, V>, where K represents the type parameter of the keys of the map and V represents the type parameter of the values of the map).
In your example, you are using a raw HashMap (raw types are types that allow for generic type parameters to be specified, however the developer has not specified them). Raw types are considered bad practice and are highly error-prone, as you are experiencing right now.
HashMap allows two generic type parameters (one for the keys and another one for the values). In your case, you are using Integer for the keys and Seat for the values. Put into simple words, you are mapping integers to seats, or you can also say that your map is a map of integers to seats.
So, inside you Hall class, you should define your map with its generic type parameters:
private Map<Integer, Seat> mySeats = new HashMap<>();
Then, this code:
h1.getMySeats().get(2)
will return an instance of type Seat, because your map already knows that all its values are of type Seat.
So your code:
h1.getMySeats().get(2).isReserved();
will compile fine and will work without any errors.
Please note that, apart from declaring the generic types of your map, I've also changed two additional things.
First, I've created an actual instance of HashMap by using its constructor:
mySeats = new HashMap<>()
If you don't create an instance of your type with new, there won't be any HashMap instance where to put your seats later, and you'll get a NullpointerException (try it!).
Secondly, I've changed the type of the variable from HashMap to Map. HashMap is a class, while Map is just an interface. The thing is that the HashMap class implements the Map interface, so, unless your code explicitly needs to access a method of HashMap that is not declared in the Map interface (which is almost never the case), you will be fine with the mySeats variable being of type Map<Integer, Seat> instead of HashMap<Integer, Seat>. This is called programming to the interface and is a best practice that you should embrace from the very beginning. It will save you a lot of headaches in the future.
Following my tip in the comments, I wouldn't use a Map to link a meaningful row or number to a map-key or an array-index.
So, actually I would do it this way (because you asked, what I mean with my tip):
Seat:
public class Seat {
private final int row;
private final int number;
private boolean reserved = false;
public Seat(int row, int number) {
this.row = row;
this.number = number;
}
public boolean reserve() {
if (!reserved) {
reserved = true;
return reserved;
}
return !reserved;
}
public int getRow() {
return row;
}
public int getNumber() {
return number;
}
public boolean isReserved() {
return reserved;
}
public boolean is(int row, int number) {
return this.row == row && this.number == number;
}
#Override
public int hashCode() {
int hash = 7;
hash = 23 * hash + this.row;
hash = 23 * hash + this.number;
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Seat other = (Seat) obj;
if (this.row != other.row) {
return false;
}
return number == other.number;
}
}
Hall:
public class Hall {
public final Set<Seat> seats = new HashSet<>();
public Set<Seat> getSeats() {
return Collections.unmodifiableSet(seats);
}
public void createSeats(int lastRow, int seatsPerRow) { // This is an example; in case you have different count of seats per row, you better make an boolean addSeat(int row, int number) function; boolean to check if it has been added or if the seat already exists
for (int row = 1; row <= lastRow; row++) {
for (int number = 1; number <= seatsPerRow; number++) {
seats.add(new Seat(row, number));
}
}
}
public Seat get(int row, int number) {
for (Seat seat : seats) { // or you use seats.iterator; I personally hate Iterators; it is my subjective point of view.
if (seat.is(row, number)) {
return seat;
}
}
return null;
}
public boolean reserve(int row, int number) {
Seat seat = get(row, number);
if (seat != null) {
return seat.reserve();
}
return false;
}
}
And my Test-drive:
public class TestDrive {
public static void main(String[] args) {
Hall hall = new Hall();
int lastRow = 15;
int seatsPerRow = 10;
hall.createSeats(lastRow, seatsPerRow);
boolean reserved = hall.reserve(5, 9);
System.out.println("Seat(Row=5, Number=9) is reserved: " + (reserved == hall.get(5, 9).isReserved()));
boolean reservedAgain = hall.reserve(5, 9);
System.out.println("Seat(Row=5, Number=9) cannot be reserved again: " + (reservedAgain != hall.get(5, 9).isReserved()));
}
}
h1.getMySeats().get(2).isReserved();
Please use an IDE like IntelliJ IDEA. It will tell you about mistakes like forgetting parentheses while typing.
I'm still a little confused with regards to the difference between static and dynamic. From what I know dynamic uses object while static use type and that dynamic is resolved during runtime while static is during compile time. so shouldn't this.lastName.compareTo(s1.lastName) use dynamic binding instead?
key.compareTo(list[position-1]) use dynamic binding
public static void insertionSort (Comparable[] list)
{
for (int index = 1; index < list.length; index++)
{
Comparable key = list[index];
int position = index;
while (position > 0 && key.compareTo(list[position-1]) < 0) // using dynamic binding
{
list[position] = list[position-1];
position--;
}
list[position] = key;
}
}
Why does (this.lastName.compareTo(s1.lastName)) use static binding?
private String firstName;
private String lastName;
private int totalSales;
#Override
public int compareTo(Object o) {
SalePerson s1 = (SalePerson)o;
if (this.totalSales > s1.getTotalSales())
{
return 1;
}
else if (this.totalSales < s1.getTotalSales())
{
return -1;
}
else //if they are equal
{
return (this.lastName.compareTo(s1.lastName)); //why is this static binding??
}
}
Your question isn't complete and doesn't include all relevant the code. However this is the basic difference between the different bindings
Java has both static and dynamic binding. Binding refers to when variable is bound to a particular data type.
Static/Early binding is done at compile time for: private, final and static methods and variables. And also for overloaded methods
Dynamic/late binding is done at runtime for: methods which can be overriden methods. This is what enables polymorphic behaviour at runtime.
To further demonstrate this point have a look at this code and see if you can determine when it would be early and late binding:
/* What is the output of the following program? */
public class EarlyLateBinding {
public boolean equals(EarlyLateBinding other) {
System.out.println("Inside of overloaded Test.equals");
return false;
}
public static void main(String[] args) {
Object t1 = new EarlyLateBinding(); //1
Object t2 = new EarlyLateBinding(); //2
EarlyLateBinding t3 = new EarlyLateBinding(); //3
Object o1 = new Object();
Thread.currentThread().getStackTrace();
int count = 0;
System.out.println(count++);
t1.equals(t2);//n
System.out.println(count++);
t1.equals(t3);//n
System.out.println(count++);
t3.equals(o1);
System.out.println(count++);
t3.equals(t3);
System.out.println(count++);
t3.equals(t2);
}
}
Answer:
++ is after the count and hence the result returned is the 0 before incrementing it. Hence starts with 0 and proceeds as you expect.
The only scenario where the equals methods of EarlyLateBinding object
is actually invoked is is statement 3.
This is because the equals method is overloaded (Note: the different
method signature as compared to the object class equals)
Hence the type EarlyLateBinding is bound to the variable t3 at
compile time.
.
in this code
public static void insertionSort (Comparable[] list)
{
for (int index = 1; index < list.length; index++)
{
Comparable key = list[index];
int position = index;
while (position > 0 && key.compareTo(list[position-1]) < 0)
{
list[position] = list[position-1];
position--;
}
list[position] = key;
}
}
key can be anything that implements the Comparable interface so in the compile time compiler doesn't know the exact type so type is resolved in the runtime by using the object that key referring to.
But in this code,
#Override
public int compareTo(Object o) {
SalePerson s1 = (SalePerson)o;
if (this.totalSales > s1.getTotalSales())
{
return 1;
}
else if (this.totalSales < s1.getTotalSales())
{
return -1;
}
else //if they are equal
{
return (this.lastName.compareTo(s1.lastName));
}
}
compiler knows the type of the s1 so it use the static binding
public void run() {
moveTest();
}
private int moveTest() {
while (frontIsClear()) {
move();
for (int i = 0; i < 0; i++);
}
}
There is the code, I want to basically count the loop (in order to find the middle point of an straight line, and then store the count into an ' int ' and than use that int (value) in another private method (or public if it needs to).
Thanks in advance hope you guys can understand my point ^^
Your question is not clear and strange, but I thing you can just create a private field in a class, return the result of method moveTest in it, and then use it in another method...
Like:
private int count = 0;
public void run() {
count = moveTest();
// use 'count'variable
}
private void someMethodUsingCountVariable() {
int a = count;
}
I have a filter class wherein the user must declare the type (e.g. Filter<Double>, Filter<Float> etc). The class then implements a moving average filter so objects within the class must be added. My question is how to do this? I'm sorry if the answer is simple but I've muddled myself up by thinking about it too much I think :p.
public abstract class FilterData<T>
{
private final List<T> mFilter;
private T mFilteredValue; // current filtered value
protected Integer mSize = 10;
private T mUnfilteredValue; // current unfiltered value
public FilterData()
{
mFilter = new ArrayList<T>();
}
public FilterData(int size)
{
mSize = size;
mFilter = new ArrayList<T>(mSize);
}
public abstract T add(final T pFirstValue, final T pSecondValue);
#SuppressWarnings("unchecked")
public T filter(T currentVal)
{
T filteredVal;
mUnfilteredValue = currentVal;
push(currentVal);
T totalVal = (T) (new Integer(0));
int numNonZeros = 1;
for (int i = 0; i < mFilter.size(); ++i)
{
if (mFilter.get(i) != (T) (new Integer(0)))
{
++numNonZeros;
T totalValDouble = add(mFilter.get(i), totalVal);
totalVal = totalValDouble;
}
}
Double filteredValDouble = (Double) totalVal / new Double(numNonZeros);
filteredVal = (T) filteredValDouble;
mFilteredValue = filteredVal;
return filteredVal;
}
public T getFilteredValue()
{
return mFilteredValue;
}
public List<T> getFilterStream()
{
return mFilter;
}
public T getUnfilteredValue()
{
return mUnfilteredValue;
}
public void push(T currentVal)
{
mFilter.add(0, currentVal);
if (mFilter.size() > mSize)
mFilter.remove(mFilter.size() - 1);
}
public void resizeFilter(int newSize)
{
if (mSize > newSize)
{
int numItemsToRemove = mSize - newSize;
for (int i = 0; i < numItemsToRemove; ++i)
{
mFilter.remove(mFilter.size() - 1);
}
}
}
}
Am I right to include the abstract Add method and if so, how should I extend the class correctly to cover primitive types (e.g. Float, Double, Integer etc.)
Thanks
Chris
EDIT:
Apologies for being unclear. This is not homework I'm afraid, those days are long behind me. I'm quite new to Java having come from a C++ background (hence the expectation of easy operator overloading). As for the "push" method. I apologise for the add method in there, that is simply add a value to a list, not the variable addition I was referring to (made a note to change the name of my method then!). The class is used to provide an interface to construct a List of a specified length, populate it with variables and obtain an average over the last 'x' frames to iron out any spikes in the data. When a new item is added to the FilterData object, it is added to the beginning of the List and the last object is removed (provided the List has reached the maximum allowed size). So, to provide a continual moving average, I must summate and divide the values in the List.
However, to perform this addition, I will have to find a way to add the objects together. (It is merely a helper class so I want to make it as generic as possible). Does that make it any clearer? (I'm aware the code is very Mickey Mouse but I wanted to make it as clear and simple as possible).
What you're trying to do is create a Queue of Number objects with a fixed size, over which you want to calculate an average. With the trivial situation that you have size = 2 and store two integers 1 & 2 you have an average of 1.5 so its reasonable to set the return type of your filter method to double.
You can then write this code similar to this
public abstract class FilterData<T extends Number> {
private final Queue<T> mFilter = new LinkedList<T>();
protected Integer mSize;
public FilterData() {
this(10);
}
public FilterData(int size) {
mSize = size;
}
public double filter(T currentVal) {
push(currentVal);
double totalVal = 0d;
int numNonZeros = 0;
for (T value : mFilter) {
if (value.doubleValue() != 0) {
++numNonZeros;
totalVal += value.doubleValue();
}
}
return totalVal / numNonZeros;
}
public void push(T currentVal) {
mFilter.add(currentVal);
if (mFilter.size() > mSize)
mFilter.remove();
}
public void resizeFilter(int newSize) {
if (mSize > newSize) {
int numItemsToRemove = mSize - newSize;
for (int i = 0; i < numItemsToRemove; ++i) {
mFilter.remove();
}
}
mSize = newSize;
}
}
You should note that this isn't thread safe.