UPDATE:: OK i am putting the original problem statement here
Given the Main class create a method createPerson and call it in any other method more than once, then on the basis of the number of times the createPerson has been executed you have to initialize the objects and input names of students and output the names.
once i come to know how many objects i have to create its quite trivial to program the later part
for the prior problem of finding the number of objects to be created i have chosen the way of file handling as i come from a C, C++ background where file handling is comparatively simple.
now how should i modify the program such that i write an integer in the file, and later when i will read the file i will get the number of objects
this example forbids the use of static variable, it is a sort of brain teaser
so do Not use static
this is my Main.java file
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
int i;
Student[] totalStudents = new Student[10];
Student.create3Persons();
Student.create2Persons();
}
}
and this is my Student.java file
import java.io.*;
public class Student {
private static void createPerson() throws IOException{
int number=0;
File file = new File("arg.txt", null);
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);
FileInputStream fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(fis);
while(dis.readInt()!= -1)
{
number++;
dos.writeInt(1);
}
}
static void create2Persons() throws IOException{
Student.createPerson();
Student.createPerson();
}
static void create3Persons() throws IOException{
Student.createPerson();
Student.createPerson();
Student.createPerson();
}
}
How should i modify this program so that i calculate how many times has been the function createPerson being called??
If you want to calculate how many times a static method has been called, you have to use a static variable - it's genuinely global state. EDIT: Yes, you can use the file system as another repository for global state, but I'd personally say that's generally a bad idea - particularly if it's just to get round a requirement in an academic question.
I guess there are some exceptions to this - if the static method is provably only called from one class, and that class is a singleton, then there could be an instance method in that singleton... but that's pretty much a corner case. In your case, create3Persons and create2Persons are both accessible from anywhere in the package, and they aren't instance methods in a singleton, so therefore there's no single context in which to keep the call count except a static variable.
Perhaps if you could explain a bit more about what you're trying to achieve, we could help you more...
EDIT: Yes, if you can rely on cooperative callers - and you can change the method signatures - then you could keep (say) an AtomicInteger, and make sure you always pass a reference to the same object into the createStudent method. Again, we'd really need to know what the rules of the question are...
i have to disagree with #Jon Skeet, i dont think you have to use a static variable. Why not simply return the number of items created, and keep the total count in a local variable in your main method ? (assuming youre allowed to modifiy method signatures of course, otherwise youre stuck with the global variable solution) you seem to have an unused counter right there already, why not use it?
You can use:
synchronized(this){
System.setProperty("methodCounter",number++);
}
instead of a file based counter. And in the main method:
System.getProperty("methodCounter");
Use AOP (Aspect-Oriented Programming).
You can use a system property to store the quantity of calls...this way you don't have to use the file system or AOP or change method signature.
Mostly when we want to retain value across method, either we go for
Static variable
or pass the variable as reference
or pass the variable and return the updated variable and use it again
int createPerson(int counter);
i got the Solution
instead of file handling i am doing this
static int createPerson(int c){
return (++c);
}
static int create2Persons(int c) {
return Student.createPerson(Student.createPerson(c));
}
static int create3Persons(int c) {
return Student.createPerson(Student.createPerson(Student.createPerson(c)));
}
public static int create5Persons(int i) {
return Student.createPerson(Student.createPerson(Student.createPerson(Student.createPerson(Student.createPerson(i)))));
}
and in the main method i have initialised an integer and i do this
c += Student.create2Persons(i)-1;
c += Student.create3Persons(i)-1;
c += Student.create5Persons(i)-1;
System.out.println(c+"c is");
this saves use of files
how to tag the thread as answered?
Related
I would like to write a general method readfile() to a class to use it on the subclasses to read all lines.
I have trouble with how to call methods from one class to another.
First, is it better to make void readfile() ?
or return a File?
Secondly, which is the way to reused from other classes?
Example of my code:
public class Reader{
Scanner myReader = new Scanner(myObj);
public void readFile(){
File myObj = new File("filename.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
}
}
public class ReadContentOfFile extends Reader{
public List<String> parseFile{
List<String> name = new ArrayList<>();
//how to get lines? as I have them, from
another method?
//for example If I want to get the
words,separated, by comma
return name;
}
}
public void Main(){
}
For example for each line of a file, how I get each element.
My problem is about how to get the data for another method, for another class.
First, is it better to make void readfile() ? or return a File?
Depends on what you want to do with the output, since you are printing the contents to console then you don't have to return the file and void is OK.
But if you wanted to use this file after you call the readFile method then you must return it or set it to class member.
Secondly, which is the way to reused from other classes?
make your method static, so you can access it without creating an object since it's just a utility and object is not important here.
public static void readFile(){
//..
}
then do
Reader.readFile()
Please, do not use Scanner to read a file, there are simpler and better options.
First, a File itself it's nothing but a reference and it won't contain any content
related to the file on system. So, you can consider to return a File object only if you may need some information from the file-system about privileges, existence, perform deleting actions or retrieving path information.
Usually when i write methods to read() or save() a file i make them void.
About how do you read data and access it, in java there are a lot of possibilities.
I'll show you one pretty straightforward:
List<String> lines = Files.readAllLines(Paths.get("filename.txt"), StandardCharsets.UTF_8);
And that's it but there are more options.
I was recently reading a java class where the person had created methods via IDE shortcut( extract method shortcut ). All methods had a return type of void and what was supposed to be return type was passed as input parameter for the method. Below is an example of what i'm referring to.
public void multiply(Integer first, Integer second, Integer result){
result = first * second;
}
I was wondering if the above is a good way of doing things. I personally do not like the above way of creating methods. I think the method should have been like below.
public Integer multiply(Integer first, Integer second, Integer result){
return first * second;
}
But in IntelliJ/Eclipse when we do extract method mostly creates method like above.
Can someone please let me know why IDE's usually create void method when we use the extract method shortcut and is the 1st style of method definition a good practice at all?
If the method being called isn't being assigned to a variable, Eclipse has no way to know what the return value is supposed to be.
Presumably, the original code looked something like this:
public static void main(String args[]){
Integer result = 0;
multiply(1,3,result);
}
There's no way for Eclipse to divine that multiply is supposed to return anything, so it defaults to void. If you want to infer return values, have it be assigned to a variable like so:
public static void main(String args[]){
Integer result = 0;
result = multiply(1,3,result);
}
I've read all the theory I can on how synchronised methods operate, but I need a practical example.
What is the positive and negative or using synchronised like this:
public class Test {
public static void main(String[] args){
boolean sync = Boolean.valueOf(args[0]);
Person person1 = person2 = new Person();
person1.write(sync, args[1]);
person1.read(sync);
person2.write(sync, args[1]);
person2.read(sync);
}
}
write is naming the project: (either synchronized or not)
public static String project_name = "";
and read is printing the current name for the person (either synchronized or not)
So what is the difference when write and read are regular methods versus synchronised methods?
What could go wrong if I use the regular method?
Quick answer:
A non-synchronous method being accessed by multiple sources will generally cause undefined behaviour, but a synchronised method will work every time.
Longer answer:
I don't think you fully understand what a synchronised method is, because your code does not demonstrate it at all.
If there really is a possibility of 100 people accessing the same method then you will have undefined behaviour when the same variable is being written to and read from.
However, if that method is accessed synchronously then each method call will be added to a queue and will happen in order.
For example:
100 different threads(People?) could call SynchronizedProjectName.renameProject("exampleName"); and/or SynchronizedProjectName.projectName(); on the code below, and no error would occur, and no read/write would happen at the same time.
public class SynchronizedProjectName {
private string project_name = "";
public synchronized void renameProject(String newProjectName) {
project_name = newProjectName;
}
public synchronized string projectName() {
return project_name;
}
}
You should always always use some sort of thread safe strategy when dealing with multiple threads/users, and if you don't, then you should expect your code to misbehave and probably crash.
See here for a little bit of extra info: https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
I have a dilemma because I don't know what is better solution. I have a static variable.
I wonder what is the best practice of declaring these variables.
Let's suppose that I have such a variable in myStatic class.
public class myStatic(){
public static int integer = 0;
/* get value */
public int getInteger() {
return integer;
}
/* set value */
public void setInteger(int nInteger) {
integer = nInteger;
}
}
Now I must increment this variables or decrements.
How to do it correctly?
1)
myStatic.integer++;
2)
myStatic mystatic = new myStatic();
int integer = mystatic.getInteger();
int nInteger = integer+1;
mystatic.setInteger(iInteger);
Is better using solution 1 or 2?
I would go with number 1, 100%, maybe just because I'm lazy, but kind of also because of:
Don't repeat yourself
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Keep it simple, stupid
This principle has been a key, and a huge success in my years of software engineering. A common problem among software engineers and developers today is that they tend to over complicate problems.
You aren't gonna need it
Principle of extreme programming (XP) that states a programmer should not add functionality until deemed necessary.
If that variable needs to be accessed everywhere and at any time, you should go with option 1.
It will act as an Environment variable even tho its not reallyyyy the same thing.
more info on env vars:
https://en.wikipedia.org/wiki/Environment_variable
Static variables need not be accessed through an object. Infact it is a waste of code.
Consider this :
public class MyStatic {
public static int i = 0;
}
You can directly access the static variable like this :
private MyStatic myStatic = null;
myStatic.i++;
This is because, the JVM doesn't even care about the object for a static property.
since static vars are class variables, they can be manipulated by any object, unless you declare a static variable as private, you had to access to it via public static methods. Then, your first approach is correct, in the second the method getInteger() does not work.
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
I recomend you to read about the singleton pattern design.
I am calling a method from a class and it gives me an error to make the method static. I am confused about why, as I asked this question What's the difference between a class variable and a parameter in a constructor? and my understanding was that class variables were made static.
Patient class:
public String setOption(String option) throws IOException
{
option = stdin.readLine();
//stuff here
return option;
}
Patient management system:
public class PatientManagementSystem
{
static BufferedReader stdin = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) throws IOException
{
Patient.setOption(null);
}
}
The error:
Do I change the method to static or create a local variable?
Based on your earlier question, I think may not be fully digging the concept of the local variable. In this method:
public String setOption(String option) throws IOException
{
option = stdin.readLine();
return option;
}
option is a local variable. You pass the initial value for that variable as an argument to the setOption method each time you call it (and you happen to ignore that value), but with that detail out of the way, this is the same as
public String setOption() throws Exception
{
String option = stdin.readLine();
return option;
}
Now, local variables are something completely different from instance or class variables: they are valid only within a method body, and exist only during the time that method is executing. With that in mind, let's look at this code:
static BufferedReader stdin = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) throws IOException
{
Patient.setOption(null);
}
Here you are basically misusing a class variable stdin for something which should have been a local variable:
public static void main(String[] args) throws IOException
{
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
Patient.setOption(null);
}
On to the question of your method call... setOption is currently an instance method, which means it must be called in the context of an instance. You are calling it as-is, with no instances of Patient involved. If you continue down this road, you won't be able to represent more than a single patient, probably not your idea. So you want to keep the method as it is and create an instance of Patient:
Patient p = new Patient();
p.setOption(...);
In your overall design it is not clear what role setOption should play, but it is not a good idea that it uses the static stdin variable (I already made it local above). You want to pass any data read from stdin into the setOption method and thus decouple it from the input reading logic.
You (probably) need to create an object of the Patient class.
Patient myPatient = new Patient();
myPatient.setOption(null);
It's hard to necessarily know what you want to do with such limited information. I don't know what you intend to do with the Patient class, but my best guess? It makes sense to do it this way, given you're trying to call a method with a setter naming convention.
If you don't intend to instantiate an object and go the route of making setOption a static method, then you should probably change the method name.
With a more in-depth explanation of what exactly you're trying to accomplish (not even talking pseudo-code, just a very abstract idea of what you're trying to do), it would be easier to explain more about static here (with your specific example) and what you should be doing, etc.
Do I change the method to static or create a local variable?
Both is OK.
If your method doesn't use class variables, it's better to make it static, so you do not have to instantiate the class for the method call.
The question of when to make something static vs. non-static is based on the real-world object/concept being modeled. Let's take the example of the Patient object in this code. Without seeing any code about the Patient, it's still pretty clear what a Patient is and what it represents. So, at its simplest:
If you're doing something with a particular Patient (let's say Jane Doe), then it's not static. It's operating on an instance of a Patient.
If you're doing something regarding the concept of a Patient, then it's static.
So some non-static operations might be:
Update the Patient's name
Admit/discharge the Patient from a hospital
Transfer the Patient to a different Doctor
All of these would involve a specific Patient, which would have been initialized somewhere:
var janeDoe = new Patient("Jane Doe");
// ...
janeDoe.TransferTo(doctorSmith);
I'm actually having trouble thinking of some static methods for a Patient. The most common example of a static method is probably a factory method, where you get an existing Patient or collection of Patients. Something like:
var janeDoe = Patient.Fetch("Jane Doe");
or:
var todaysPatients = Patient.Fetch(DateTime.Today);
Various helper methods are often static as well, perhaps a method on the Patient object which accepts a MedicalRecord object and converts it to a different format, for example.
But the overall idea is the same. If you're interacting with a specific instance of an object, then you need an instance of that object to represent that real-world concept.
Because you are directly calling that method without creating object of class.
When to have static methods?
To call a method in a static way, you have to make it static :
public static String setOption(String option) throws IOException
But in your example if stdin is not a static member of your Patient class, it can't work.
To sum up, you can call a method the way you call it when it's declared static. In a static method you can access only static members of your class.
Try this in your main method :
Patient myPatient = new Patient();
myPatient.setOption(null);
We create classes with static methods when we intend to use those methods as utility methods, like parseInt in the class Integer. thus either modify the method
public static String setOption(String option) throws IOException // STATIC
{
option = stdin.readLine();
//stuff here
return option;
}
and then use the method like
Patient.setOption(null);
OR instantiate an object for Patient like
Patient obj = new Patient();
obj.setOption(null);
In Java main method is special. It's the starting point of your code. Static methods could be called from anywhere in your code. Thus actually it does not belong to the containing class. It's also true for the main method.
Thus you should construct your object in the main method and then use the constructed instance's methods. If you do not construct your an instance, then your ide will recognise the error and suggest you to make it static.