Loop through hashmap to create a class instance with inside functions - java

I am making a bukkit plugin, and I am using an API called MCStats, to create the graph, you add Plotters like so...
mobs.addPlotter(new Metrics.Plotter("Player") {
#Override
public int getValue() {
return 0;
}
});
But I want to get the values from a HashMap, and idealy something like this...
for(String mob: mobNames) {
mobs.addPlotter(new Metrics.Plotter(mob) {
#Override
public int getValue() {
return Stats.getValue(mob);
}
});
}
But obviously, it can't access the mob variable, if I set it to final, it still wont be able to change in the loop. How can I work around this problem?

You can, in fact, use final in an enhanced for loop:
for(final String mob: mobNames) {
mobs.addPlotter(new Metrics.Plotter(mob) {
#Override
public int getValue() {
return Stats.getValue(mob);
}
});
}

You can use the final keyword for mob and it still be changed in the loop.
Try to run this code below:
public class Test2 {
public static void main(String args[]) {
String[] data = new String[] {"1", "2"};
List<MyClass> test = new ArrayList<MyClass>();
for (final String word: data) {
test.add(new MyClass() {
#Override
public void testMethod() {
System.out.println(word);
}
});
}
for (MyClass myClass: test) {
myClass.testMethod();
}
}
static class MyClass {
public void testMethod() {
}
}
}
The output will be "1" and "2".

Related

How to access the value of string by the inheritance?

import java.util.*;
class Pilot
{
protected String PILOT = "BSIT-1A";
public static void Subject()
{
String[] subs = {"Comprog11","WebDev","Digilog12","ComProg12"};
}
public static void Teacher()
{
String[] teach = {"Ms.a","Ms.b","Ms.c","Ms.d"};
}
}
class Pilot1 extends Pilot
{
protected String PILOT1 = "BSIT-1B";
public static void main(String[]args)
{
Pilot1 obj = new Pilot1();
System.out.println(obj.PILOT);
System.out.println(obj.PILOT1);
obj.Subject();
obj.Teacher();
}
how to display the values of Subject() and Teacher() if I put inside it a String?It doesnt have any compiler issues but when I ran it display only the
BSIT-1A
BSIT-1B
my expected output is
BSIT-1A
BSIT-1B
Comprog11
Webdev
Digilog12
Comprog12
Ms.a
Ms.b
Ms.c
Ms.d
You can return the array
public String[] subject() {
return {"Comprog11","WebDev","Digilog12","ComProg12"};
}
Then remove the inheritance. You don't need it for the main method. Make the pilot constants public or pass those strings into a class constructor and add a private field with a getter method, for example
Pilot a = new Pilot("BSIT-1A");
Pilot b = new Pilot("BSIT-1B");
System.out.println(a.getCode());
System.out.println(b.getCode());
Arrays.stream(a.subject()).forEach(System.out::println);
You need the either print the values in Subject() and Teacher() or make them return the values. Also calling static methods via objects is not a
good practice. They should be invoked by the class, like Pilot1.Subject().
class Pilot
{
protected String PILOT = "BSIT-1A";
public static void Subject()
{
String[] subs = {"Comprog11","WebDev","Digilog12","ComProg12"};
for(String sub : subs){
System.out.println(sub);
}
}
public static void Teacher()
{
String[] teach = {"Ms.a","Ms.b","Ms.c","Ms.d"};
for(String t : teach){
System.out.println(t);
}
}
}

Creating a method that creates multiple lists inside a class

i wanted to know if you can create a method inside a class that can create more than 1 list
public class UnidadeSaude {
private String NomeUnidade;
public UnidadeSaude() {
}
public UnidadeSaude(String NomeUnidade) {
this.NomeUnidade = NomeUnidade;
}
public String getNomeUnidade() {
return NomeUnidade;
}
public void setNomeUnidade(String nomeUnidade) {
NomeUnidade = nomeUnidade;
}
void gravar(String NomeUnidade){
List<String> UnidadeSaude = new ArrayList<String>();
UnidadeSaude.add(NomeUnidade);
}
void ler() {
System.out.print(UnidadeSaude);
}
}
First: in Java, variable names are written in camelCase and Classes in PascalCase.
This is extremely important to difference between objects and Class references.
Second: I think you're trying to write names into a List in the gravar() method.
You can do it by having a static List in the class. You can add them to the list and then print them in the ler() method.
public class UnidadeSaude {
private String nomeUnidade;
private static List<String> nomeUnidades = new ArrayList();
public UnidadeSaude() {
}
public UnidadeSaude(String nomeUnidade) {
this.nomeUnidade = nomeUnidade;
}
public String getNomeUnidade() {
return nomeUnidade;
}
public void setNomeUnidade(String nomeUnidade) {
this.nomeUnidade = nomeUnidade;
}
void gravar(String NomeUnidade) {
nomeUnidades.add(NomeUnidade);
}
void ler() {
for (String nome : nomeUnidades) {
System.out.println(nome);
}
}
}
HOWEVER, I don't recommend this! It doesn't semantically make sense to store multiple objects into a class that represents a single object. You should ideally store them in a List outside that class

How to pass down the new operator in a method

For example, if I wanted to do something like this to call a method:
myLights.addLight(new Fluorescent(lumens));
in order to create a new object in the Fluorescent class and pass down the lumens data. How would I then set up the method to receive this?
Assuming method is not returning anything.
void addlight(Fluorescent a){
// your logic
}
In your Lights class create a method that accepts a Fluorescent object as an argument.
public void addLight(Fluorescent fluorescent){
// do something
}
Here is a basic example:
public class HelloWorld
{
public static void main(String[] args)
{
Light light = new Light();
light.addLight(new Fluorescent("300 lm"));
System.out.print(light.getLumen());
}
}
public class Light {
private String lumen;
public Light() {
}
public void setLumens(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
public void addLight(Fluorescent fluorescent) {
if(fluorescent.getLumen() != null) {
this.lumen = fluorescent.getLumen();
}
}
}
public class Fluorescent {
private String lumen;
public Fluorescent(String lumen){
this.lumen = lumen;
}
public void setLumen(String lumen){
this.lumen = lumen;
}
public String getLumen(){
return this.lumen;
}
}
Seeing that a Fluorescent is a Light, you might want to look in to inheritance.
Look here for some explanation
Java 101: Inheritance in Java, Part 1
public class Fluorescent() {
public Fluorescent(String lumens) {
// do something
}
}
public class Lights() {
public void addLight(Fluorescent fluorescent) {
// do something
}
}

Varying the order of method calling for different instances of a class

What is the best way of manipulating the order things are done based on some conditions (other than writing them again with the different order)?
Let's say there is a Person class and each object of Person represents a different human.
class Person{
int eatingPriority = 3;
int sleepingPriority = 2;
int recreationPriority = 1;
void eat() {/*eats*/}
void sleep() {/*sleeps*/}
void watchTv() {/*watches tv*/}
void satisfyNeeds() {
//HOW TO DO THIS
}
}
How can I make the satisfyNeeds() methods call the other three methods based on their priority?
Note: I want to make it clear that priorities can change from Person to Person.
You can do this with 1 class and 1 interface.
public class Person {
int eatingPriority = 3;
int sleepingPriority = 2;
int recreationPriority = 1;
PriorityQueue<Action> actions;
void eat() { }
void sleep() { }
void watchTv() { }
public Person() {
actions = new PriorityQueue<Action>(new Comparator<Action>() {
#Override
public int compare(Action o1, Action o2) {
return o2.getPriority() - o1.getPriority();
}
});
actions.add(new Action() {
#Override
public int getPriority() {
return eatingPriority;
}
#Override
public void execute() {
eat();
}
});
actions.add(new Action() {
#Override
public int getPriority() {
return sleepingPriority;
}
#Override
public void execute() {
sleep();
}
});
actions.add(new Action() {
#Override
public int getPriority() {
return recreationPriority;
}
#Override
public void execute() {
watchTv();
}
});
}
public void satisfyNeeds() {
for (Action action : actions) {
action.execute();
}
}
interface Action {
public int getPriority();
public void execute();
}
}
Here is another possible implementation :
abstract class Need {
abstract void satisfy();
}
class Eat extends Need {
#Override
public void satisfy() { /* eat ...*/}
}
class Sleep extends Need {
#Override
public void satisfy() { /* sleep ...*/}
}
class DrinkBeer extends Need {
#Override
public void satisfy() { /* drink beer ...*/}
}
class Person{
// TreeMap will sort the map in the key's natural order (a int here)
private Map<Integer, Need> needs = new TreeMap<>();
Person() {
add(new Eat(), 3);
add(new Sleep(), 2);
add(new DrinkBeer(), 1);
}
void add(Need need, int priority) {
needs.put(Integer.valueOf(priority), need);
}
void satisfyNeeds() {
for(Need need : needs.values())
need.satisfy();
}
}
This solution would require Java 8:
class Person {
void eat() {};
void sleep() {};
void watchTv() {};
// Being in a List you can easily reorder the needs when you want to
List<Runnable> needs = Arrays.asList(this::eat, this::sleep);
// Alternatively, you can use a Map<Runnable, Integer> where the value is your
// priority and sort it (see http://stackoverflow.com/q/109383/1296402)
void satisfyNeeds() {
needs.forEach(Runnable::run);
}
}
You can use this code
import java.util.Arrays; // must be imported
int[] priorities = {sleepPriority, eatPriority, recreationPriority};
Arrays.sort(priorities);
for (int i=priorities.length-1; 0<=i; i--) {
int priority = priorities[i];
if (priority == sleepingPriority) { sleep(); }
if (priority == eatingPriority) { eat(); }
if (priority == recreationPriority) { watchTv(); }
}
Basically, it puts the priorities in an array, sorts the array and runs a for loop on it to run the functions.
Finding the right order of three elements can be done simply like this:
void satisfyNeeds() {
boolean eatFirst = eatingPriority>Math.max(sleepingPriority,recreationPriority);
if(eatFirst) eat();
if(sleepingPriority>recreationPriority) {
sleep();
watchTv();
}
else {
watchTv();
sleep();
}
if(!eatFirst) eat();
}
Of course, it won’t scale if you raise the number of actions. For a higher number you might look at one of the other answers.
You should introduce a map property into Person class, where prioritize methods, for example:
class Person {
...
private Map<Integer, Method> methodsPriority = new HashMap<>();
...
public Person setEatingPriority(int priority) {
methodsPriority.put(priority, /* put 'eat' method reference here*/);
return this;
}
public Person setSleepingPriority(int priority) {
methodsPriority.put(priority, /* put 'sleep' method reference here*/);
return this;
}
public Person setWatchingTVPriority(int priority) {
methodsPriority.put(priority, /* put 'watch TV' method reference here*/);
return this;
}
public void satisfyNeeds() {
Collection<Integer> keys = methodsPriority.keySet();
Collections.sort(keys);
for(Integer key: keys)
methodsPriority.get(key).invoke(this);
}
...
}
And it can be used in next manner:
Person Anna = new Person()
.setEatingPriority(1)
.setSleepingPriority(2)
.setWatchingTVPriority(3);
Person Bob = new Person()
.setEatingPriority(3)
.setSleepingPriority(2)
.setWatchingTVPriority(1);
Anna.satisfyNeeds();
Bob.satisfyNeeds();

Java: get results from anonymous class operation

I want to do something like this:
public class ScadenzaService {
...
public List<Scadenza> tutteLeScadenze() {
List<Scadenza> scadenze = null;
txm.doInTransaction(new TransactionAction() {
#Override
public void perform() {
scadenze = dao.getAll(Scadenza.class);
}
});
return scadenze;
}
But I can't access scadenze in the inner class, since it's not final. However, final wouldn't help: it makes a constant.
What's the workaround?
Make scadenze final and initialise it to a new List. Inside your anon class you can still add to the list; being declared final does not prevent this.
public List<Scadenza> tutteLeScadenze() {
final List<Scadenza> scadenze = new ArrayList<Scadenza>();
txm.doInTransaction(new TransactionAction() {
#Override
public void perform() {
scadenze.addAll(dao.getAll(Scadenza.class));
}
});
return scadenze;
}

Categories

Resources