This question already has answers here:
Unable to access a method's local variables outside of the method in Java
(4 answers)
Closed 2 years ago.
How do i get the value of the int count to be declare in a setText outside of its inner class?
model.getSearch().observe(this, new Observer<List<Sight>>() {
#Override
public void onChanged(#Nullable List<Sight> searchList) {
adaptersearch = new SearchAdapter(SearchResults.this, searchList);
searchhList.setAdapter(adaptersearch);
int count = 0;
if (adaptersearch != null) {
count = adaptersearch.getItemCount();
}
}
});
apptxt.setText(count +name+ "items");
At the minute it just comes up with the error cannot resolve count.
You can't write to a variable (change the value of the variable ) that has been initialized in outer class from an inner class.
there is a workaround to do it is to create a final array of int with one value, then you can access it in your inner class.
keep in mind that this is not the best way to do it.
If this is really the scenario you are looking for one way of doing it is using an int wrapper or using AtomicInteger which is helpful should there be threads involved there:
final AtomicInteger count = new AtomicInteger(0);
model.getSearch().observe(this, new Observer<List<Sight>>() {
#Override
public void onChanged(#Nullable List<Sight> searchList) {
adaptersearch = new SearchAdapter(SearchResults.this, searchList);
searchhList.setAdapter(adaptersearch);
if (adaptersearch != null) {
count.set(adaptersearch.getItemCount());
}
}
});
apptxt.setText(count.get() +name+ "items");
What you are experiencing is that the reference should be final in that case and therefore you must change the value inside the object as you cannot change the reference.
Related
This question already has answers here:
Assigning variables with dynamic names in Java
(7 answers)
Closed 3 years ago.
I'm trying to make a program in which an object is declared every time a loop is passed through.
package sequence;
public class SequenceServer {
SequenceObj sequence = new SequenceObj();
public void findSequence(int[] sequence, int lastNumber) {
for(int i = 0; i < sequence.length; i++) {
SequenceObj sequenceTemp = new SequenceObj(); // this line is wrong, but I don't know how to make it work
}
}
}
There are no errors, but I need to make it so a potentially infinite number of variables can be declared through the user interacting with the program, as opposed to me individually declaring all of the variables.
Try this:
`public class SequenceServer {
SequenceObj sequence;
public void findSequence(int[] sequence, int lastNumber) {
for(int i = 0; i < sequence.length; i++) {
sequence = new SequenceObj(); // this line is wrong,
// but I don't know how to make it work
}
}
}`
This question already has answers here:
Variable used in lambda expression should be final or effectively final
(9 answers)
Is there any way to change value captured by Java Lambda
(2 answers)
How to use non-final variable inside Java8 streams/filters?
(3 answers)
Closed 4 years ago.
I am using Vert.x after working with Node.js for a few years and am trying to replicate some of the functionality we'd see in require('async')
package huru.util;
import java.util.ArrayList;
import java.util.List;
interface AsyncCallback {
public void cb(Object e, Object v);
}
interface AsyncTask {
public void run(AsyncCallback cb);
}
interface FinalCallback {
public void run(Object e, List<Object> v);
}
public class Async {
static void Parallel (List<AsyncTask> tasks, FinalCallback f) {
List<Object> results = new ArrayList<Object>();
int count = 0;
for(int i = 0; i < tasks.size(); i++){
tasks.get(i).run((e,v) -> {
if(e != null){
f.run(e, null);
return;
}
count++; // ! here, count needs to be final ??
results.set(i,v);
if(count == tasks.size()){
f.run(null, results);
}
});
}
}
}
the above is getting there, but I get this error:
Variable used in lambda expression should be final or effectively
final
I assume it's a similar problem that we see in JS where the value of i might change as the loop continues.
Anyone know how to mitigate this one? Wrapping it in a self-invoking function would be how to do this with JS.
This question already has answers here:
Why can't enum's constructor access static fields?
(5 answers)
Closed 6 years ago.
I have an enum with values like this (the example just shows a few of the values but you will catch on): _800, _830, _900, _24HOURS, CLOSED
These have a corresponding value, so I added to my enum, which you can do in Java, a value field and a getter and setter for the value, like this (for space sake I do not show the getter and setter but they are the standard ones):
enum Hours {
_800("08:00"),
_830("08:30"),
CLOSED("Closed"),
APPT("By Appt.")
// etc
;
Hours(String v) {
val = v;
}
String val;
}
I also want to be able to go the other direction, that is, if I have a value (e.g. "08:00") I want it to return the enum _800. So to the enum I added a map:
static Map<String,String> valToEnumMap = new HashMap();
then I added this to my constructor:
Hours(String v) {
val = v;
valToEnumMap.put(v, this);
}
and a new method:
Hours valToEnum(String v) {
return valToEnumMap(v);
}
but when I try running it I get an initialization error at the point where it tries to insert into the map. I have tried other things like
valToEnumMap.put(v, valueOf(name());
but the same error. I did find a workaround but it is very slow, so I wonder what I did wrong? Here is the workaround I used which is slow:
public static OfficeHoursTimes valToEnum(String val) {
for (OfficeHoursTimes o : OfficeHoursTimes.values()) {
if (o.getVal().equals(val)) {
return o;
}
}
return null;
}
But there has to be a better way
The problem is that you're trying to use the map before it's initialized, since your enum instances get created first.
You want to declare your map like this:
static final Map<String,Hours> valToEnumMap = _createValueMap();
and then
private static Map<String,Hours> _createValueMap()
{
Map<String, Hours> map = new HashMap<>();
//...iterate through values() and put them all in the map ...
return map;
}
At first glance, it seems your map is defined wrong.
Try
static Map<String,Hours> valToEnumMap = new HashMap<String,Hours>();
This question already has answers here:
How do I restrict object creation not more than 3 in Java class?
(8 answers)
Closed 9 years ago.
I want to create maximum five objects of a class. If more than times object are created it will throw an exception. Please help.
Create a static factory method that keeps track of the instances created.
With a private constructor, the users have to use the factory method, which can then throw the exception if more than 5 objects have already been created.
Do something like this:
public class VeryOddClass
{
private static final Object lock = new Object();
private static int s_count;
static
{
s_count = 5; /*ToDo - read from configuration*/
}
public VeryOddClass()
{
synchronize(lock){
if (s_count <= 0) throw new VeryOddClassException();
--s_count;
}
/*normality resumes from here*/
But do rethink your design requirements.
I think would be the solution for this kind of question. We need to have private static counter and once it reaches the desire limit then throw an exception.
class Program
{
private static int instanceCount;
public Program()
{
if (instanceCount > 5)
throw new InvalidOperationException("Only 5 instances of Program are allowed");
instanceCount++;
}
public static void main(String[] args)
{
for (int n = 0; n < 10; n++)
new Program();
}
}
make a static private field and increment it in the constructor. Also, check there for the count. Increment it by TheClassname.field++ or something and check by TheClassname.field==5
Instantiate your class via a factory and limit it to 5 instances using a simple counter. Or use a modified Singleton:
OOPS (Design Patterns)
I am having some trouble with passing data of an array from one class to the next.
edits
I am now no longer getting the error, and my code compiles, but as I had been warned, I got null for every element of the array. Now that I have taken out the static modifiers though, it still gives me null. I have also updated the code.
Here is the class where the array is created.
public class AssignSeat {
String[] arrangement = new String[12];
public void SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
System.out.format("%-15s%-15s%n", "seat", "passenger");
for (int i=0; i<arrangement.length; i++) {
System.out.format("%-15s%-15s%n", i+1, arrangement[i]);
}
}
public String[] getArrangement() {
return arrangement;
}
public void setArrangement(String[] arrangement) {
this.arrangement = arrangement;
}
}
and here is the method trying to access the information. It is specifically the for loop that I need help with so Ignore other areas where there are mistakes. Thank you.
public void actionPerformed(ActionEvent event) {
Scanner scanner = new Scanner(System.in);
AssignSeat seat = new AssignSeat();
if(event.getSource() instanceof JButton){
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("first class")) {
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[1] == null)) {
System.out.println(seat.arrangement[0]);
System.out.println(seat.arrangement[2]);
two.setForeground(Color.green);
}
} else if (buttonText.equals("coach")) {
//System.out.println("so does this!");
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[4] == null)) {
five.setForeground(Color.green);
}
if ((seat.arrangement[5] == null)) {
six.setForeground(Color.green);
}
if ((seat.arrangement[10] == null)) {
eleven.setForeground(Color.green);
}
}
}
}
The problem lies in the fact that the array was declared as static, but the initialization code for it is in the constructor. Remove all the static modifiers in the original code, and replace this part:
if (AssignSeat.getArrangement()[1].equals("null"))
With this:
AssignSeat assign = new AssignSeat();
if (assign.getArrangement()[1] == null)
Also notice that "null" is not a null value, use null (without quotes) for that.
A different approach would be to leave the array as an static member, but initialize it statically, like this:
private static String[] arrangement = new String[12];
static {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
}
In that case, this would work:
if (AssignSeat.getArrangement()[1] == null)
But I still believe that making the array static is going to be problematic if several instances of the class happen to be modifying its contents.
Replace
if (AssignSeat.getArrangement()[1].equals("null"))
with
if (AssignSeat.getArrangement()[1] == null)
If the value is null, you can't invoke methods (like equals) on it. You need to compare the value directly to null, which is a constant rather than a string.
Ok, I'm a bit confused as to what you're trying to do in the first class. You are initializing a static array from an instance method...
In other words, the String values in the array will be null until you call SeatStart from an instance of the class.
Try to initialize the String array from the static constructor for AssignSeat to make sure it has been initialized before you use it: http://www.snippetit.com/2009/05/java-static-variables-static-methods-and-static-constructor/
You are trying to use an attribute of a class, without instantiating the object first. Until you call a default/user-defined constructor, there is no memory dedicated to the attribute of that object.
Even though you manage to call the method you are using a static method, which can be called without an instance of the object being required.
Create a constructor for the object (or use a default constructor) and then you will be able to access your attribute because your object will be on the heap and have memory allocated for the string[].
Simply define the SeaStart as an Array.
public String[] SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
return arrangement;
}
For convinience, make a new array to copy the array from AssignSeat class. Then retrieve the value from that array.
public void actionPerformed(ActionEvent event) {
AssignSeat seat = new AssignSeat();
String[] foo = seat.SeatStart();
System.out.println(foo[0]);
System.out.println(foo[1]);
System.out.println(foo[2]);
}
Though you can acces it also with:
System.out.println(seat.SeatStart()[0]);
The result would be:
Collins
null
Faivre
and that 'null' is because apparently you haven't allocate a value for arrangement[1] :-)
But in the end, it works.