Use Reference Variable - java

I have two class ,following:
first Class:
package MemoryInterfaces;
import java.util.SortedSet;
import java.util.TreeSet;
/**
*
* #author omid
*/
public class MemoryData<T> {
private Object _datas =null;
public MemoryData() {
}
/**
* #return the _data
*/
public SortedSet<T> getDatas() {
if (this._datas==null) {
this._datas=new TreeSet<T>();
getDataOfDatabase();
}
return (SortedSet<T>)_datas;
}
/**
* #param data the _data to set
*/
public void setDatas(SortedSet<T> datas) {
this._datas=datas;
}
public T getDataOfMemory(int i) {
return (T) getDatas().toArray()[i];
}
public void addItem(T data) {
this.getDatas().add(data);
}
public void remove(T data) {
this.getDatas().remove(data);
}
protected void getDataOfDatabase() {
}
}
second Class:
public class CabinetImpl extends MemoryData<CabinetItem> {
private static SortedSet<CabinetItem> _datas = null;
public CabinetImpl() {
setDatas(_datas);
}
#Override
protected void getDataOfDatabase() {
CabinetDaoImpl _cab = new CabinetDaoImpl();
List<Cabinet> _lst = _cab.getTable();
if (!_lst.isEmpty()) {
for (int i = 0; i < _lst.size(); i++) {
AddToMemory(_lst.get(i).getID(), _lst.get(i).getName(), _lst.get(i).getSub(), _lst.get(i).getDepid());
}
_datas=getDatas();
}
}
private void AddToMemory(int id, String name, int sub, int depid) {
CabinetItem _cab = new CabinetItem(id, name, sub, depid);
addItem(_cab);
}
}
in second Class ,I have a static varible(_datas) be when constructing of cabinetImpl class,_datas transfer to MemoryData but not effect changes in MemoryData on _datas.
Please Help Me!

You are not allowed to override a private variable of a super class in an inherited class. Use the getters and setters of MemoryData

You have two different fields with the same name in different classes.
They are no relationship to each other and different types. If you want to have only one copy I suggest removing one of them.

Related

How to update static variable by passing the parameters of the same variable and nonstatic ones into static function in java?

package staticassignment3;
public class Booking {
private String customerEmail;
private int seatsRequired;
private static int seatsAvailable;
private boolean isBooked;
static {
seatsAvailable = 400;
}
public Booking(String customerEmail, int seatsRequired) {
this.customerEmail = customerEmail;
this.seatsRequired = seatsRequired;
}
public String getCustomerEmail() {
return this.customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail= customerEmail;
}
public int getSeatsRequired() {
return this.seatsRequired;
}
public void setSeatsRequired(int seatsRequired) {
this.seatsRequired = seatsRequired;
}
public static int getSeatsAvailable() {
return Booking.seatsAvailable;
}
public static void setSeatsAvailable(int seatsAvailable) {
Booking.seatsAvailable = Booking.seatsAvailable - this.seatsRequired;
}
public boolean isBooked() {
if(Booking.seatsAvailable>= this.seatsRequired) {
Booking.setSeatsAvailable(seatsAvailable);
this.isBooked = true;
}
else {
this.isBooked = false;
}
return isBooked;
}
}
In the above Booking class, I want to update the static variable seatsAvailable by using the static method setSeatsAvailable but I am passing a nonstatic variable in it i.e this.seatsRequired which is not permitted. Is there any alternative to update the seatsAvailable without changing the code so much?
package staticassignment3;
public class Tester {
public static void main(String[] args) {
Booking booking1 = new Booking("jack#email.com", 100);
Booking booking2 = new Booking("jill#email.com", 350);
Booking[] bookings = { booking1, booking2 };
for (Booking booking : bookings) {
if (booking.isBooked()) {
System.out.println(booking.getSeatsRequired()+" seats successfully booked for "+booking.getCustomerEmail());
} else {
System.out.println("Sorry "+booking.getCustomerEmail()+", required number of seats are not available!");
System.out.println("Seats available: "+Booking.getSeatsAvailable());
}
}
}
}
in above Booking class i want to update seatsAvailable static variable by using setSeatsAvailable static method but i am passing nonstatic varible in it i.e this.seatsRequired which is not permitted.is there any alternate to achive the updated seatsAvailable static varibale without doing major changes in code
When calling a static method, there is no assocated object instance. So, it is not valid to use this inside a static method, since this refers to the current object (but you have none).
Specfically, this method isn't correct:
public static void setSeatsAvailable(int seatsAvailable) {
Booking.seatsAvailable = Booking.seatsAvailable - this.seatsRequired;
}
If you want to keep the method static, you could pass an additional parameter to the method – an instance of Booking – and then replace this.seatsRequired with booking.seatsRequired, like this:
public static void setSeatsAvailable(int seatsAvailable, Booking booking) {
Booking.seatsAvailable = Booking.seatsAvailable - booking.seatsRequired;
}

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

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

fireEvent from Custom class

I have the following class ProtokollEvent
public class ProtokollEvent extends Event {
//variable holds all devices in given protokoll
private ObservableList<Device> devicesList;
//variable holds SaveResult
private SaveResult result;
//final ProtokollEvents
public static final EventType<ProtokollEvent> PROTOKOLL_SAVE = new EventType(ANY, "PROTOKOLL_SAVE");
public static final EventType<ProtokollEvent> PROTOKOLL_SAVE_DONE = new EventType(ANY, "PROTOKOLL_SAVE_DONE");
public static final EventType<ProtokollEvent> PROTOKOLL_UPDATED = new EventType(ANY, "PROTOKOLL_UPDATED");
public static final EventType<ProtokollEvent> PROTOKOLL_DELETED = new EventType(ANY, "PROTOKOLL_DELETED");
public ProtokollEvent() {
this(PROTOKOLL_SAVE);
}
public ProtokollEvent(EventType<? extends Event> arg0) {
super(arg0);
}
public ProtokollEvent(Object arg0, EventTarget arg1, EventType<? extends Event> arg2) {
super(arg0, arg1, arg2);
}
/**
* getDevices will return current {#link Device} as ObservableList
*
* #return {#link ObservableList} of type {#link Device}
*/
public ObservableList getDev() {
return devicesList;
}
/**
* setDevices will set devicesList
* #param devices ObservableList {#link Device}
*/
public void setDev(ObservableList devices) {
this.devicesList = devices;
}
/**
* get the result which is returned from calling saveProtokoll
* #return result {#link SaveResult}
*/
public SaveResult getResult() {
return result;
}
/**
* set the result which is returned after calling saveMessprotokoll in RestCall
* #param result {#link SaveResult}
*/
public void setResult(SaveResult result) {
this.result = result;
}
}
in the second class
public class SaveUtils {
private MainWindowController controller;
private ObservableList<RowContainerPruefvorschriftController> rows;
private Protokoll lastSavedProtokoll;
private Protokoll currentSavingProtokoll;
public SaveUtils(MainWindowController control){
this.controller = control;
}
private void startSaving(){
currentSavingProtokoll = createProtokoll();
boolean state = controller.networkOnline.get() ? saveOnline() :saveOffline();
}
public void setRows(ObservableList<RowContainerPruefvorschriftController> rows) {
this.rows = rows;
//if rows get set start saveing the data
startSaving();
}
private boolean saveOffline(){
return false;
}
private boolean saveOnline() {
RestCall call = controller.getCall();
//call saveMessprotokoll and look what SaveResult returns
SaveResult result = call.saveMessprotokoll(currentSavingProtokoll);
//create ProtokollEvent to tell all consumers if all was ok
ProtokollEvent save = new ProtokollEvent(ProtokollEvent.PROTOKOLL_SAVE_DONE);
save.setResult(result);
//HOW to fire/dispatch the ProtokollEvent here??????
//TODO: need to fire this event and listen for it in other classes
if(result.getResult()>0){
controller.setLoggerMessage("SavedOnline->Protokoll-Nr.:"+result.getProtokollnr());
}
else {
controller.setLoggerMessage("SavedOnline not successful->Error:"+result.getError_message());
}
return true;
}
}
in the saveOnline function i create a ProtokollEvent and pass it some values.
What i now want is to fire or dispatch this event so other code parts could listen to this.
I tried with fireEvent() but as i understood the Oracle-DOCs only NODEs, Windows and Scene are able to do so. But how could i solve it with my custom class?
Additional i ask myself whats is the difference between fireEvent and dispatchEvent?
Found the solution.
All events could be fired through the static method
Event.fireEvent(EventTarget eventTarget,Event event)
where eventTarget specifies the path through which the event will travel (taken from java docs).
So for my example i just added the following line
Event.fireEvent(controller.getMainWindowBorderPane(),save);
did it...

HashMap<String[], List<int[]>> not detecting a duplicate value

I am trying to add data to my hashmap if the key does not already exist in the map. For some reason, even if the key does exist, the hashmap adds it anyways. I have no idea why this is happening. My addEntity method is the problem. I am trying to detect of the key is already in the hashmap, and if it is, then do nothing. However, it for some reason will always add the key, no matter if the key already exists.
My data file:
package timeTraveler.mechanics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.minecraft.entity.EntityLiving;
public class PathingData
{
/**
* Entity data array
*/
public static Map<String[], List<int[]>> allEntityData;
public PathingData()
{
allEntityData = new HashMap<String[], List<int[]>>();
}
/**
* Adds an entity UUID (Unique ID)and MobType to the entity data ArrayList. If the entity already exists inside of the ArrayList, then it skips it.
* #param uuid
*/
public void addEntity(String[] entityData)
{
System.out.println(entityData[0]);
if(!allEntityData.containsKey(entityData))
{
System.out.println("Adding entity!");
allEntityData.put(entityData, new ArrayList<int[]>());
}
else
{
System.out.println("ENTITY ALREADY EXISTS IN ARRAY");
}
}
/**
* Adds data (X, Y, and Z) to the corresponding UUID (Unique ID) for the entity. If the entity's UUID does not exist, then it prints out a line that says the UUID cannot be found.
* #param uuid
* #param data
*/
public void addData(String[] entityData, String data)
{
System.out.println(entityData[0]);
if(allEntityData.containsKey(entityData))
{
System.out.println("Adding data to entity!");
int[] rawData = new int[3];
String[] pureData = data.split(",");
rawData[0] = Integer.parseInt(pureData[0]);
rawData[1] = Integer.parseInt(pureData[1]);
rawData[2] = Integer.parseInt(pureData[2]);
List<int[]> entityLocData = allEntityData.get(entityData);
entityLocData.add(rawData);
allEntityData.put(entityData, entityLocData);
}
else
{
System.out.println("ENTITY DOES NOT EXIST IN ARRAY! :(");
//addEntity(entityData);
}
}
/**
* Gets the data for a specific UUID (Unique ID) for an entity.
* #param uuid
* #return
*/
public List<int[]> getDataForUUID(String[] entityData)
{
List<int[]> entityLoc = allEntityData.get(entityData);
return entityLoc;
}
/**
* Clears all entities and their corresponding data from the map.
*/
public void clearAllEntitiesAndData()
{
allEntityData.clear();
}
/**
* Checks if entity exists inside of array
* #param uuid
* #return
*/
public boolean doesEntityExist(String[] entityData)
{
List<int[]> entityLoc = allEntityData.get(entityData);
if(entityData != null)
{
return true;
}
return false;
}
}
I have made sure that there is only one instance of the variable, and I always refer to that one variable in my .addEntity and .addData. Any ideas?
EDIT: I have just now tried to implement the suggestion proposed. However, it still just prints out the same thing, with timetraveler.core.StringArrayHolder#0 instead of the array. Here is the modified code:
package timeTraveler.mechanics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import timeTraveler.core.StringArrayHolder;
import net.minecraft.entity.EntityLiving;
public class PathingData
{
/**
* Entity data array
*/
public static Map<StringArrayHolder, List<int[]>> allEntityData;
public PathingData()
{
allEntityData = new HashMap<StringArrayHolder, List<int[]>>();
}
/**
* Adds an entity UUID (Unique ID)and MobType to the entity data ArrayList. If the entity already exists inside of the ArrayList, then it skips it.
* #param uuid
*/
public void addEntity(StringArrayHolder entityData)
{
System.out.println(entityData);
if(!allEntityData.containsKey(entityData))
{
System.out.println("Adding entity!");
allEntityData.put(entityData, new ArrayList<int[]>());
}
else
{
System.out.println("ENTITY ALREADY EXISTS IN ARRAY");
}
}
/**
* Adds data (X, Y, and Z) to the corresponding UUID (Unique ID) for the entity. If the entity's UUID does not exist, then it prints out a line that says the UUID cannot be found.
* #param uuid
* #param data
*/
public void addData(StringArrayHolder entityData, String data)
{
System.out.println(entityData);
if(allEntityData.containsKey(entityData))
{
System.out.println("Adding data to entity!");
int[] rawData = new int[3];
String[] pureData = data.split(",");
rawData[0] = Integer.parseInt(pureData[0]);
rawData[1] = Integer.parseInt(pureData[1]);
rawData[2] = Integer.parseInt(pureData[2]);
List<int[]> entityLocData = allEntityData.get(entityData);
entityLocData.add(rawData);
allEntityData.put(entityData, entityLocData);
}
else
{
System.out.println("ENTITY DOES NOT EXIST IN ARRAY! :(");
//addEntity(entityData);
}
}
/**
* Gets the data for a specific UUID (Unique ID) for an entity.
* #param uuid
* #return
*/
public List<int[]> getDataForUUID(StringArrayHolder entityData)
{
List<int[]> entityLoc = allEntityData.get(entityData);
return entityLoc;
}
/**
* Clears all entities and their corresponding data from the map.
*/
public void clearAllEntitiesAndData()
{
allEntityData.clear();
}
/**
* Checks if entity exists inside of array
* #param uuid
* #return
*/
public boolean doesEntityExist(StringArrayHolder entityData)
{
List<int[]> entityLoc = allEntityData.get(entityData);
if(entityData != null)
{
return true;
}
return false;
}
}
and the wrapper:
package timeTraveler.core;
import java.util.ArrayList;
public class StringArrayHolder
{
private String[] data;
public StringArrayHolder()
{
data = new String[2];
}
public void setData(String[] data)
{
this.data = data;
}
public String[] getData()
{
return this.data;
}
#Override
public int hashCode()
{
return 0;
//...
}
#Override
public boolean equals(Object o)
{
if(data.equals(o))
{
return true;
}
return false;
//...
}
}
The problem is that arrays don't override equals nor hashCode methods from Object class, thus even if you add a new String[] with the same values, it will be a different key in your map.
A possible solution would be creating a wrapper class that will hold the String[] for you and override the equals and hashCode methods there.
public class MyStringArrayHolder {
private String[] data;
//class constructor...
//getters and setters for the array...
#Override
public int hashCode() {
//...
}
#Override
public boolean equals(Object o) {
//...
}
}
For the implementations of equals and hashCode methods, you can use Arrays#equals and Arrays#hashCode in this wrapper class.
From your comment:
My addEntity method is the problem. I am trying to detect of the key is already in the hashmap, and if it is, then do nothing. However, it for some reason will always add the key, no matter if the key already exists.
This is what I've explained above. The method Map#containsKey clearly states this:
returns true if and only if this map contains a mapping for a key k such that (key==null ? k==null : key.equals(k))
Since arrays does not override Object#equals, you won't have two similar array keys even if they have the same elements in the same position.
EDIT: based on your current edit, the problems are in the equals and hashCode methods implementation. I've made a basic implementation of the MyStringArrayHolder class and copied/pasted the code of the PathingData class. This works as expected (at least for this case):
class MyStringArrayHolder {
private final String[] data;
//I do not want any client could change the array reference
//this also explains why this field doesn't have a setter
public MyStringArrayHolder(String[] data) {
this.data = data;
}
public String[] getData() {
return this.data;
}
#Override
public int hashCode() {
return Arrays.hashCode(data);
}
#Override
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (o instanceof MyStringArrayHolder) {
MyStringArrayHolder other = (MyStringArrayHolder)o;
return Arrays.equals(this.data, other.data);
}
return false;
}
//just to print in console for testing purposes
#Override
public String toString() {
return Arrays.deepToString(data);
}
}
public class PathingData {
//removed the static modifier, not really sure why you need it like that
public Map<MyStringArrayHolder, List<int[]>> allEntityData;
//current class implementation...
//just to print in console for testing purposes
#Override
public String toString() {
return allEntityData.toString();
}
public static void main(String[] args) {
PathingData pathingData = new PathingData();
String[] example1 = { "hello", "world" };
String[] example2 = { "luiggi", "mendoza" };
String[] example3 = { "hello", "world" };
MyStringArrayHolder holder1 = new MyStringArrayHolder(example1);
MyStringArrayHolder holder2 = new MyStringArrayHolder(example2);
MyStringArrayHolder holder3 = new MyStringArrayHolder(example3);
pathingData.addEntity(holder1);
pathingData.addEntity(holder2);
pathingData.addEntity(holder3);
pathingData.addData(holder1, "1,2,3");
pathingData.addData(holder2, "4,5,6");
pathingData.addData(holder3, "7,8,9");
System.out.println(pathingData);
}
}
Output:
Adding entity!
Adding entity!
ENTITY ALREADY EXISTS IN ARRAY
Adding data to entity!
Adding data to entity!
Adding data to entity!
{[luiggi, mendoza]=[[I#35087359], [hello, world]=[[I#5a7691c0, [I#1e5b02a6]}
Note: the last line containing [I#35087359 is the current hash code of the int[]. I would recommend to change from List<int[]> to List<List<Integer>>, but this implementation is outside the scope of the question :).

Can not access members outside

public class TableModel extends AbstractTableModel {
public int page;
public TableModel(Integer p) {
this.page=p;
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
#Override
public int getRowCount() {
return data.size() ;
}
Can not access variable page in getgroup() method it passes 0 to getgroup() method.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Your question is unclear, but I suspect the problem is just that all the instance initializers are being run before the constructor body, so you're seeing the default value for page. You should have something like:
public class TableModel extends AbstractTableModel {
private static final String[] columnNames =
{"groupName","membersCount","previliage"}; // TODO: Fix spelling!
private final int page;
private final List<GroupData> data;
public TableModel(int page) {
this.page = page;
this.data = new DatabaseLayer().getGroup(page);
}
...
}
It's generally a good idea to keep all your instance/static variable declarations in one place (I prefer to keep them at the top, but YMMV) and make them all private to make it easier to reason about how they're used. The main change, however, is moving the new DatabaseLayer ().getGroup(page) code into the constructor.
public class TableModel extends AbstractTableModel {
public int page;
public ArrayList<GroupData> data;
public TableModel(Integer p) {
this.page=p;
this.data = (new DatabaseLayer ()).getGroup(page);
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
#Override
public int getRowCount() {
return data.size() ;
}
Refresh your data field every time when you assign a new value to the page field.
public TableModel(int p) {
setPage(p);
}
public void setPage(int p) {
this.page = p;
this.data = new DatabaseLayer ().getGroup(page);
}
This is absolute correct because:
public int page;
default value for page is 0 because its int.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Is a variable initialization so before initialization of page you are passing it into .getGroup(page) so default value will pass in that case.
So you have to call getGroup(int) method after page being initialized, one way can be following:
private final List<GroupData> data;
public TableModel(Integer p) {
this.page = p;
this.data = new DatabaseLayer().getGroup(page);
System.out.println("mm"+page);
}

Categories