retrieve instantiated objects from hashmap - java

I really didn't want to resort to asking, however I'm at a dead end. I'm trying to build an array of objects stored within a hashmap into a single array. I'm building a minecraft plugin, and I need to be able to do this in order to reset all players to their natural state. However, for whatever reason, I can't seem to actually parse the Spectator[] array into individual pieces.
The goal is simply to allow more than 1 person to spectate. Here's my code:
public class EagleEye extends JavaPlugin implements Listener{
public HashMap<Spectatee, Spectator[]> spec = new HashMap(Spectatee, Spectator[]);
public HashMap<Spectatee, Spectator[]> orinven = new HashMap<Spectatee, Spectator[]>;
public HashMap<Spectatee, Spectator[]> eeinven = new HashMap<Spectatee, Spectator[]>;
#Override
public void onEnable()
{
//TODO:Who knows.
}
#Override
public void onDisable()
{
//TODO:Spec off any players being spectated and spectating.
Spectator[] frickinhell = spec.get(key));
//Creates a master list of all spectators by uuid
for(Spectator spec : spec.get(Spectator.class))
{
master.add(spec);
}
for(Object spec : master.toArray())
{
//Verify the player is online
if(Bukkit.getPlayer(master)
{
//Verify the player is still spectating
if(tators.get(uuid) == true)
{
//Stop spectating
tators.put(uuid, false);
}
}
}
}
I understand that much of this code is broken. However, my main concern is taking Spectator[] stored within all instances of Spectators[] stored within the hashmap and resetting their values to their defaults. Once I can access each individual instance of each object itself, I can reset their respective values using setters.
Cheers.

In spec.get(Spectator.class), Spectator.class doesn't match the type of your key, which is Spectatee. Therefore, it returns null.
You should pass an instance of Spectatee to spec.get() if you want to have a chance of getting a non-null value.
If you want to collect all the Spectators regardless of their key, you can iterate over the values of the Map :
for (Spectator[] value : spec.values())
for(Spectator spec : value)
{
master.add(spec);
}

Related

unsafe.compareAndSwapObject replacing an array that is being iterated in another thread

I am trying to implement logic that will allow me to update an array in one thread using sun's unsafe.compareAndSwapObject utility while safely iterating over that same array, in a different thread. I believe that the CopyOnWriteArrayList does what I am searching for however it uses locking for the updating and I am trying to develop a solution that does not have any locks.
The compare and swap logic is as follows:
public void add(final Object toAdd) {
Object[] currentObjects;
Object[] newObjects;
do {
currentObjects = this.objects;
newObjects = ArrayUtil.add(currentObjects, toAdd);
} while (!UNSAFE.compareAndSwapObject(this, OBJECTS_OFFSET, currentObjects, newObjects));
}
While the iteration logic is as follows (the toString() is a placeholder):
public void doWork() {
Object[] currentObjects = this.objects;
for (final Object object : currentObjects) {
object.toString();
}
}
My questions are:
Is this code safe?
Does this give me the same snapshot behaviour that CopyOnWriteArrayList does?
If it does, when is the iteration snapshot formed?
Does the fact that I'm creating a local variable have anything to do this?
If it does, how does the JVM know to not optimise this away?
Have I essentially created a variable on the stack that has a reference to the most up to date array object?
Lastly to follow up the third point above about "snapshot" creation, would the following code work the same way:
public void doWork() {
actuallyDoWork(this.objects);
}
public void actuallyDoWork() {
for (final Object object : currentObjects) {
object.toString();
}
}

Rewrite labels using methods

So to be more specific I want to be able to do "changeLabel(lableHere, textHere);"
but I don't know how to specify the label.
to simplify my request I want to go from
public static void method1(String TextToSet){
if(variable.isVisible()==false){
variable.setVisible(true);
variable.setText(TextToSet);
}else if(variable.isVisible()==true){
variable.setVisible(false);
}
}
public static void method2(String TextToSet){
if(variable2.isVisible()==false){
variable2.setVisible(true);
variable2.setText(TextToSet);
}else if(variable2.isVisible()==true){
variable2.setVisible(false);
}
}
or what I'm using currently:
public static void method(String VariableIWantToChange, String TextToSet){
if(VariableIWantToChange.equalsIgnoreCase("Variable1"){
if(Variable1.isVisible()==false){
Variable1.setVisible(true);
Variable1.setText(TextToSet);
}
else if(Variable1.isVisible()==true){
Variable1.setVisible(false);
}
}
if(VariableIWantToChange.equalIgnoreCase("Variable2"){
if(Variable2.isVisible()==false){
Variable2.setVisible(true);
Variable2.setText(TextToSet);
}
else if(Variable2.isVisible()==true){
Variable2.setVisible(false);
}
}
}
(that method becomes really long after just a few variables)
and instead, have one method that is something like this
public static void method( Labeltochange ,String TextToSet){
if(Labeltochange.isVisible()==false){
Labeltochange.setVisible(true);
Labeltochange.setText(TextToSet);
}
}
that allows you to change label by doing method(LabelToChange, TextToSet);
The real requirement here: you want to map a name (String) name to some UI element (maybe a JLabel, maybe a JButton, who cares).
The answer: use a n appropriate data structure, like a Map<String, JComponent>.
Simply fill that map at some point in time:
Map<String, JComponent> componentsByName = new HashMap<>(); ...
componentsByName.put("label1", labelA);
So, later on, you simply do a componentsByName.get() to retrieve ... a component by its "name". To then call whatever method you want to invoke on that object.
In other words: you absolutely should not get into the business of doing such if/else chains. Every time your UI gets a new thing, or an element gets removed, you have to update code in a zillion of places.

Why is boolean flag within the method body a bad idea?

Suppose I have something as follows where DataImporter is a utility to retrieve data from the file system and has child data importers within it for retrieving data from the sub folders based on the category string:
List<String> categories = getCategories();
boolean doesChildImporterExist = false;
for (String category : categories)
{
DataImporter childDataImporter=importer.getChild(category);
if (childDataImporter != null)
{
doesChildImporterExist = true;
populateImportedData(childDataImporter.importData());
}
}
if(!doesChildImporterExist)
populateImportedData(importer.importData());
I know the other option is to construct a List of child data importers and check for its size, if it is 0 or not and based on that import the data using the desired importer. However, I'm trying to understand what is wrong with using the boolean flag here?
Assume that the code above is within a method and using Java 1.7.
When you use a boolean flag in a method as a branch decider (not the best terminology),
you are actually taking the functionality of two different methods and smashing them into one method.
Often,
the better solution is to have a method for the shared functionality and a second method for the super set functionality.
For example:
public DataImporter doYourCategoryStuff()
{
List<String> categories = getCategories();
... blah including the for loop.
return theDataImporter;
}
public void doAllTheStuffs()
{
final DataImporter theDataImporter;
theDataImporter.doYourCategorStuff();
populateImportedData(theDataImporter.importData());
}
Edit
More to the point in your code.
In your code,
the boolean flag indicates "I did something to a child importer and need to update parent importer".
In this case you are smashing "identify things to update" and "do the update" together;
split them.
Consider something like this:
Set<DataImporter> updateSet = new HashSet<>();
for (category for loop)
{
final DataImporter child = importer.getChild(category);
if (child != null)
{
updateSet.add(child);
updateSet.add(importer);
}
}
for (final DataImporter current : updateSet)
{
current.importData();
}
Even though the add(importer) (the parent) may be called multiple times,
the set will only ever contain one instance of each DataImporter.
This should be reasonable even if you don't implement hashCode and equals on DataImporter, since the parent reference will always be the same.

How should I implement Guava cache when I plan to cache multiple values efficiently?

I have a Java class that has a Guava LoadingCache<String, Integer> and in that cache, I'm planning to store two things: the average time active employees have worked for the day and their efficiency. I am caching these values because it would be expensive to compute every time a request comes in. Also, the contents of the cache will be refreshed (refreshAfterWrite) every minute.
I was thinking of using a CacheLoader for this situation, however, its load method only loads one value per key. In my CacheLoader, I was planning to do something like:
private Service service = new Service();
public Integer load(String key) throws Exception {
if (key.equals("employeeAvg"))
return calculateEmployeeAvg(service.getAllEmployees());
if (key.equals("employeeEff"))
return calculateEmployeeEff(service.getAllEmployees());
return -1;
}
For me, I find this very inefficient since in order to load both values, I have to invoke service.getAllEmployees() twice because, correct me if I'm wrong, CacheLoader's should be stateless.
Which made me think to use the LoadingCache.put(key, value) method so I can just create a utility method that invokes service.getAllEmployees() once and calculate the values on the fly. However, if I do use LoadingCache.put(), I won't have the refreshAfterWrite feature since it's dependent on a cache loader.
How do I make this more efficient?
It seems like your problem stems from using strings to represent value types (Effective Java Item 50). Instead, consider defining a proper value type that stores this data, and use a memoizing Supplier to avoid recomputing them.
public static class EmployeeStatistics {
private final int average;
private final int efficiency;
// constructor, getters and setters
}
Supplier<EmployeeStatistics> statistics = Suppliers.memoize(
new Supplier<EmployeeStatistics>() {
#Override
public EmployeeStatistics get() {
List<Employee> employees = new Service().getAllEmployees();
return new EmployeeStatistics(
calculateEmployeeAvg(employees),
calculateEmployeeEff(employees));
}});
You could even move these calculation methods inside EmployeeStatistics and simply pass in all employees to the constructor and let it compute the appropriate data.
If you need to configure your caching behavior more than Suppliers.memoize() or Suppliers.memoizeWithExpiration() can provide, consider this similar pattern, which hides the fact that you're using a Cache inside a Supplier:
Supplier<EmployeeStatistics> statistics = new Supplier<EmployeeStatistics>() {
private final Object key = new Object();
private final LoadingCache<Object, EmployeeStatistics> cache =
CacheBuilder.newBuilder()
// configure your builder
.build(
new CacheLoader<Object, EmployeeStatistics>() {
public EmployeeStatistics load(Object key) {
// same behavior as the Supplier above
}});
#Override
public EmployeeStatistics get() {
return cache.get(key);
}};
However, if I do use LoadingCache.put(), I won't have the refreshAfterWrite feature since it's dependent on a cache loader.
I'm not sure, but you might be able to call it from inside the load method. I mean, compute the requested value as you do and put in the other. However, this feels hacky.
If service.getAllEmployees is expensive, then you could cache it. If both calculateEmployeeAvg and calculateEmployeeEff are cheap, then recompute them when needed. Otherwise, it looks like you could use two caches.
I guess, a method computing both values at once could be a reasonable solution. Create a tiny Pair-like class aggregating them and use it as the cache value. There'll be a single key only.
Concerning your own solution, it could be as trivial as
class EmployeeStatsCache {
private long validUntil;
private List<Employee> employeeList;
private Integer employeeAvg;
private Integer employeeEff;
private boolean isValid() {
return System.currentTimeMillis() <= validUntil;
}
private synchronized List<Employee> getEmployeeList() {
if (!isValid || employeeList==null) {
employeeList = service.getAllEmployees();
validUntil = System.currentTimeMillis() + VALIDITY_MILLIS;
}
return employeeList;
}
public synchronized int getEmployeeAvg() {
if (!isValid || employeeAvg==null) {
employeeAvg = calculateEmployeeAvg(getEmployeeList());
}
return employeeAvg;
}
public synchronized int getEmployeeEff() {
if (!isValid || employeeAvg==null) {
employeeAvg = calculateEmployeeEff(getEmployeeList());
}
return employeeAvg;
}
}
Instead of synchronized methods you may want to synchronize on a private final field. There are other possibilities (e.g. Atomic*), but the basic design is probably simpler than adapting Guava's Cache.
Now, I see that there's Suppliers#memoizeWithExpiration in Guava. That's probably even simpler.

Advice on Java program

My java project required that I create an array of objects(items), populate the array of items, and then create a main method that asks a user to enter the item code which spits back the corresponding item.
It took me a while to figure out, but I ended up "cheating" by using a public variable to avoid passing/referencing the object between classes.
Please help me properly pass the object back.
This is the class with most of my methods including insert and the find method.
public class Catalog {
private Item[] itemlist;
private int size;
private int nextInsert;
public Item queriedItem;
public Catalog (int max) {
itemlist = new Item[max];
size = 0;
}
public void insert (Item item) {
itemlist[nextInsert] = item;
++nextInsert;
++size;
}
public Item find (int key) {
queriedItem = null;
for (int posn = 0; posn < size; ++posn) {
if (itemlist[posn].getKey() == key) queriedItem = itemlist[posn];
}{
return queriedItem;
}
}
}
This is my main class:
import java.util.*;
public class Program {
public static void main (String[] args) {
Scanner kbd = new Scanner (System.in);
Catalog store;
int key = 1;
store = new Catalog (8);
store.insert(new Item(10, "food", 2.00));
store.insert(new Item(20, "drink", 1.00));
while (key != 0) {
System.out.printf("Item number (0 to quit) ?%n");
key = kbd.nextInt();
if (key == 0) {
System.out.printf("Exiting program now!");
System.exit(0);
}
store.find(key);
if (store.queriedItem != null) {
store.queriedItem.print();
}
else System.out.printf("No Item found for %d%n", key);
}
}
}
Thanks I appreciate the help!!!!!!
store.find(key); returns an Item you should use it and delete the public field from Catalog
public Item find (int key) {
Item queriedItem = null;
//....
}
Item searched = store.find(key);
if (searched != null)
searched.print();
else
System.out.printf("No Item found for %d%n", key);
Remove your use of queriedItem entirely and just return the item from find: Replace
store.find(key);
if (store.queriedItem != null){store.queriedItem.print();}else System.out.printf("No Item found for %d%n", key);
With
Item foundItem = store.find(key);
if (foundItem != null) {
foundItem.print();
} else System.out.printf("No Item found for %d%n", key);
Well, here are some suggesetions (choose complexity at your own discretion, but all of them is highly recommended):
Research Properties, for example here. Or XML. You could populate the array with values from a configuration file for greater flexibility.
Use constanst for literals in your code (where they are necessary).
Create an ApplicationFactory the initializes the whole application for you. Things like this need to be separated from your domain logic.
Create a UserInputProvider interface so you can easily change the way the input of the user is read without affecting anything else. Implement it with a ConsoleInputProvider class for example.
In general, try using interfaces for everything that's not a pure domain object (here, the only one you have is probably Item).
Try to keep your methods as short as possible. Instead of doing many things in a method, have it invoke other methods (grouping related logic) named appropriately to tell what it is doing.
If you're not allowed to cheat and use List or a Map, devise your own implementation of one, separating data structure and handling from the logic represented by Catalog (i.e. Catalog in turn will delegate to, for example, Map.get or equivalent method of your data structure implementation)
Your main should basically just have ApplicationFactory (or an IoC framework) to build and initialize your application, invoke the UserInputProvider (it should not know the exact implementation it is using) to get user input, validate and convert the data as required, invoke Catalog to find the appropriate Item and then (similarly to the input interface) send the result (the exact data it got, not some string or alike) to some implementation of a SearchResultView interface that decides how to display this result (in this case it will be a console-based implementation, that prints a string representing the Item it got).
Generally, the higher the level of decoupling you can achieve, the better your program will be.
The Single Responsibility Principle states: " every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class". This is also true for methods: they should have one and only one well defined task without any side effects.

Categories

Resources