I have a question about constructing an ArrayList, I have had a Car Class, now I need to make an ArrayList to put content in, I named it as Race, please see code below:
import java.util.ArrayList;
public class Race {
private ArrayList<Car>cars;
public Race(){
cars=new ArrayList<Car>();
}
Now I need to have a method for add content to the ArrayList, there are two ways to write that I am confused with:
First one
public void addCars(){
Car Toyota=new Car("Toyota",1.0,1.0,2.0,2.0);
Car Honda=new Car("Honda",1.0,2.0,1.0,2.0);
Car Mazda=new Car("Mazda",1.0,3.0,2.0,3.0);
Car Suzuki=new Car("Suzuki",1.0,4.0,4.0,2.0);
cars.add(Toyota);
cars.add(Honda);
cars.add(Mazda);
cars.add(Suzuki);
}
Second one
public void addCars(Object nm,String n, double s, double p, double a, double b){
Car name=new Car(n,s,p,a,b);
cars.add(name);
}
Both ways have no mistake reported when I coding, but I am not sure which one is correct, or maybe neither is correct, please help, cheers!
UPDATE:
public void addCars(Car car){
cars.add(car);
}
This is what I used finally, then I created a new class called Test that using main method to add cars individually, but there is mistake in the last line:
public class Test {
public static void main(String[] args) {
Car Toyota=new Car("Toyota",1.0,1.0,2.0,2.0);
**cars.addCars(Toyota);**
I have no idea how to fix it, please help!
It depends on what you want to achieve. In general it is better to provide APIs and use them from the outside. In your case, however, I think your "addCars" function in used to populate your ArrayList(you should call it something like that) - which means to add predefined values to a Collection.
In that case, use the first one.
So, both of your methods are correct (though you should call the first populateCars and the second addCar) and should work, but you need to use them depending on your circumstance.
Also, if you want to provide an API for adding Cars, let the user get a Car object himself, rather than constructing one in the add method. (You might want to change it before adding it, you never know)
So I suggest using either of the methods, but changing the first to:
public void populateCars(){
Car Toyota=new Car("Toyota",1.0,1.0,2.0,2.0);
Car Honda=new Car("Honda",1.0,2.0,1.0,2.0);
Car Mazda=new Car("Mazda",1.0,3.0,2.0,3.0);
Car Suzuki=new Car("Suzuki",1.0,4.0,4.0,2.0);
cars.add(Toyota);
cars.add(Honda);
cars.add(Mazda);
cars.add(Suzuki);
}
or the second to:
public void addCar(Car car){
cars.add(car);
}
Both the ways you mentioned are correct but you should modify the method addCars() to take an argument of type Car .
For example , change the method signature to :
public void addCars(Car car){
cars.add(car);
}
And just pass a new car like this :
addCars(new Car("Toyota",1.0,1.0,2.0,2.0));
The only difference is that in first case you have hard coded elements in the list and in the second approach you add them dynamically. What to use depends on your need.
I suppose you will use the arraylist later on to get elements from it, do sth with them etc. Then you will use getter method on the arraylist, iterate through it and so on... This will work on both approaches you choose.
Both answers are correct. The first method uses a traditional approach to creating objects. The second method is sometimes called a Factory method. Using a factory method is useful when the construction of an object is externally complicated or stamping out multiple objects.
So the answer is: The first approach is correct for objects that are reasonably simple and safe to construct. The second (factory) pattern is better for complex objects.
#pei wang nice question .. Second apporach is gud as ur not hardcoding values .. You should go little bit forward .. please Use DTO design pattern in second approach use setters and getters
Add method expects object type reference for the add method if you pass any reference variable other than object type reference variable then those reference variable upcasted to object type reference.
Related
I am providing the examples below to further illustrate my point:
Example 1:
public class A {
public String getTheNeededString() {
String returnedString;
//logic goes here
return returnedString;
}
}
public class B {
public void doSomething(A objectA) {
String neededString = objectA.getTheNeededString();
//proceed to do something that needs the above String
}
}
public class Client {
public static void main(String[] args) {
A objectA = new A();
B objectB = new B();
objectB.doSomething(objectA);
}
}
Example2:
public class A {
//stays the same
}
public class B {
public void doSomething(String neededString) {
//proceed to do something that needs the above String
}
}
public class Client {
public static void main(String[] args) {
A objectA = new A();
String neededString = objectA.getTheNeededString();
B objectB = new B();
objectB.doSomething(neededString);
}
}
I guess that there might not be a "better" approach and it might be a matter of preference.
If that's the case, then I would really appreciate any opinion/preference on the matter.
It is always preferable to pass only the required info for following reasons:
Single-responsibility principle : Each class/method should have one and only one responsibility. In this case, the method doSomething() should only know how to transform a string input into the desired output. It should not be the responsibility of this method to get the string by calling other methods.
Loosely coupled design: Imagine you decide to change the getTheNeededString() method in a way that you have to change all the calls to this method in your project. You'll have to make changes in doSomething() method as well. Here, the doSomething() method is tightly coupled to getTheNeededString() method. This is not a good design.
I believe it really is a matter of preference, and dependent on what exactly you need the program to do.
I would advise with Example 2, as it just makes more sense to me. If I were to come across your code at a later date and trying to interpret it, the second approach would be much more intuitive, at least for me.
It also makes the code reusable in the case you need to perform that same operation with any String outside of Object A. That may not be the case, but I still do not see the need to pass in the entire object. Pass the bare minimum input needed to produce the output needed.
Assume the method is to, say, count the number of occurences of the letter 'Z' and is called with countOccurencesOfLetterZ(objectA). Now, any person just exposed to this code will have to inspect this method to find out what it does - sure, the name is very intuitive.. but you're passing in the entire object, which needlessly creates uncertainty/confusion as to what you're trying to accomplish.
Now, assume you have countOccurencesOfLetterZ(objectA.getUsername()). I no longer have to inspect that method to figure out what you're trying to accomplish. Even better, if this method ends up being something you can utilize outside of Object B, then you can put it in a utility class and reuse that code for any string.
It depends on what is the goal of each class in your design.
Just an example.
Suppose class A represents a product and provides some details based on which class B creates product description. Suppose this logic is more complex that just getting a string. If you encapsulate such logic into the class B (approach 1), then if the logic changes later on, the only place to adjust will be the class B. The effort will be small and the number of bugs also small, if any. In case of the 2nd approach you will have to find all places where you pass data of object of class A to the object of class B and adjust all of them. It will take more time. Also it can happen, that you do these changes slightly differently and introduce more bugs. In such cases 1st approach is preferable.
Suppose the goal of the class B is to translate a given message key to some language, e.g. according to the default locale. In such case this class does not need to know where this key comes from (to reduce dependency on other classes). Suppose you have also other classes that provide keys that need to be translated, but they are in different class hierarchies and such objects cannot be passed to the method of class B. Then the 2nd approach is better. Each place where B is called implements its specific logic and passes to B only the common part, String key.
I have created an object that contains an Arraylist and that Arraylist contains objects. My question is, how do i point to the objects in the Arraylist?
the original Object contains:
some attributes,
list = new arraylist
The List contains:
14 objects of similar data
This seems like a fairly simple task, but because you did not give me your exact code, I am just going to assume.
Let's say this is the class of the object that you were talking about
public class ClassA {
public ArrayList<Integer> list = new ArrayList<>(); //I guess integers are "similar data"
}
Now you have that object, called obj
ClassA obj = new ClassA ();
You can just access the array list by doing this
obj.list
For example you can add an item to the array list like this:
obj.list.add(10);
And you can retrieve the first item
obj.list.get(0);
Easy!
If you think you understand little of the above, I'll explain. If you think you understand it completely, you can just accept the answer and go.
Almost every class declare members. And so does your class, ClassA. Any accessible member can be accessed using .. We call it the dot operator.
And what is an accessible member?
Different access modifiers provide different accessibility, read this to find out more: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html In the above example, list is a member, and it is declared public This means that it is accessible everywhere.
This is why you can access it using ..
Actually, I think you must have used this technique before! When you call
System.out.println ("Hello World");
You use the dot to access members!
In the System class, there is a member called out. out is of type PrintStream. In PrintStream class, there is another member called println! See? that's how Java works.
If you still don't understand, read this part again. If you understand, please click that green tick to accept the answer.
My assignment is to create a program that simulates a simple online shopping program.
we have to:
create a main menu with 3 options and then a submenu when selecting the 2nd option on the main menu.
I'm unsure how call a method from another class for example:
I have been given a method:
public void start() {
which is in the file "GroceryStore.java"
I am supposed to create a topMenu method which when the user inputs "1" calls to the method:
public void displayItems(){
^in file called "Stock.java"
which then prints out an array of items that online store has in stock. The array in the
Stock.java is
private SalesItem[] items;
Can anyone tell me how to do this? I have to do this for several things and I'm hoping I can apply the skeleton of this to the rest of the cases.
For now, I'm going to assume that Stock is an instance type(it sounds like an instance type), and It would make sense that your GroceryStore would have a reference to 1 or more Stock items.
Your Stocks will have to be instantiated with the new keyword. so
Stock myStock = new Stock(/*parameters for constructor*/);
after you do that, you can call the displayItems method of myStock like so
myStock.displayItems();
so start() is in the GroceryStore class.
So in a public static void main class you would go :
GroceryStore gs = new GroceryStore();
gs.start();
In your GroceryStore class you would have a new method which looks like (You may want to have the Stock stock = new Stock() line in the constructor of the GroceryStore object-- would make more sense:
Stock stock = new Stock();
public void topMenu(int parm){
if(parm==1)then{
stock.displayItems();
}
}
And then finally in the Stock class you have the displayItems method which may look like :
public void displayItems(){
for(int i=0;i<items.length;i++){
SalesItem temp = items[i];
System.out.prinlnt(temp.toString());//or this may be temp.getName() or whatever returns a string from this SalesItem object - I dont know what it looks like - you never said!
}
}
It is however essential you actually understand what is going on here not just copy paste and run?! This wont actually do anything anyway until you have a call to the topMenu method passing it 1, so you will need to workout how you are going to interact with your gs object whether its by keyboard input, mouse click on a gui or something else :)
To call a method outside the current instance you have multiple options:
make the method static (so that it won't be attached to any particular instance) and call it through MyClass.method(), this has sense if it is a stateless object, mostly an utility method
create a static instance variable that can be accessed (so method is not static but the specific object is), then call it through SomeClass.stock.method(), this has sense when you want a single object of a specific type throughout the program
create a normal instance variable inside the class from which you want to call the method (this has sense just if the object contained is used in a HAS-A relationship). Then you call it simply doing this.stock.method() (you can omit this)
You need to tell the compiler where to get the methods from if the method is not in the same class. The best way of doing this would be to create an object that refers to the class you're trying to reach (using the New Java keyword and the appropriate syntax, i.e. ClassName objectName = new ClassName() - you may want to include any parameters you may have).
Have a look at this other StackOverflow answer - the user had a question very similar to yours, so it may help.
Also, there is a pretty good tutorial on objects and classes on TutorialsPoint. I suggest you have a look at it and give it a go. Try understanding the concept behind what you're trying to achieve first - I can guarantee you it will help later on as this is a very fundamental concept in OO programming.
Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.
considering i have a method which gets a List passed as an param. Within this method i want to use for instance an ArrayList specific function on that list (lets say trimToSize()). What would be the general approach to deal with a problem like this ?
Here two example:
First approach (i don't think this is good)
private void doSomething(final List<T> list) {
// ... do something
((ArrayList<T>) list).trimToSize();
// ... do something
}
Second approach (i think this one is better)
private void doSomething2(final List<T> list) {
final List<T> myList = new ArrayList<T>();
// Collections.copy(myList, list); or
myList.addAll(list);
((ArrayList<T>) myList).trimToSize();
//..do something
}
I'm curious whats the best solution for a problem like this.
Well, the preferred option is to just write the method to take an ArrayList in the first place. If you need ArrayList specific functionality, the method has no business taking a List. Transfer the responsibility of ensuring that the parameter is of the right type to the caller and don't fiddle around with it inside the method.
Why not just declare method as a private void doSomething(final ArrayList<T> list), if you want only ArrayList as parameter?
If you're accepting any object implementing the List interface then your function should only invoke methods implemented from the interface.
If you want to invoke functions from ArrayList class then have ArrayList as your parameter. Much safer than either of your options.
The second we have huge overhead with big lists, but is safer. I would go for the first, but with check whether the provided List is ArrayList and then make a cast.
You should have a strong reasons to not take an ArrayList as a parameter though.
The first option you've shown only works for ArrayLists so it's not an option if you want to support any type of List. If you want to support any type of List you must convert (not cast) it to an ArrayList.
I think there might be some confusion because the List and ArrayList are so closely related (by inheritance). It is only coincidence that the parameter type and the class we need to call the function on are related in this way.
If we abstract the requirements a bit:
We need to act on a series of values
We need to use trimToSize() on the
series of values.
If the values were coming as an array there would be no question but to create a new ArrayList with the values from the array and then use trimToSize(), because casting would not be an option. It is just bad luck that the method we need trimToSize() happens to be on a subclass of List, and the author wants to pass the values as a List.
What about
private void doSomething(final List<T> list) {
final ArrayList<T> arrayList;
if (list instanceof ArrayList) {
arrayList = (ArrayList<T>) list;
} else {
arrayList = new ArrayList<T>(list);
}
...
arrayList.trimToSize();
}
Of course, I agree with Chinmay Kanchi: for a private method, it makes no sense to accept a more general type than necessary. My approach is only feasible if it causes no problems to modify the given list.
Your first method changes the List passed to the method while the other one doesn't. Two methods are not comparable.
Since it is a private method, the convention of using the List interface is not overly important. There is no public API affected so use whichever method is the most convenient for its usage in the class.
For example, if 5 other methods call this method with potentially varying types of List, then use your second option and centralize the conversion in 1 method (you can even throw in a check for type and not convert if you like). If your class only deals with ArrayList internally anyway, and you know that is what it will be when called, then declare it as a ArrayList and make your life easy for yourself.