I am creating a vector which stores the object of a particular class.
This class a String variable which is the identifier of that object.
So, I create an object and set this variable as "abc". Then after this object is destroyed I make another object and set the same variable as "abc".
Now I have to check if there is any object in vector already present with variable set as "abc".
I have tried using toString() and comparable() as such but no success.
I know I can make a loop and check for it but I was hoping for some simpler and faster way.
Thanks in advance.
Do you mean something like…
We have a class Dog.
public class Dog {
public String name;
public String color;
public ZonedDateTime dateOfBirth;
public Dog( String nameArg ) {
this.name = nameArg;
}
}
We collect instances in a Vector.
Vector dogs = new Vector( 3 );
dogs.add( new Dog( "Jupiter" ) ) ;
dogs.add( new Dog( "Jasmine" ) ) ;
dogs.add( new Dog( "Jacques" ) ) ;
Later we want to test if the Vector contains any dog by the name of "Jasmine"? Not that particular dog above, but any containing that text as its name?
Yes, looping to ask each dog's name and compare the text returned is one way.
Another way is to override the equals method to compare names. Then you can call the contains method on the vector to see if it has a matching dog object. But overriding equals is often not realistic. In this example, sharing a name does not mean we have the same dog and so we don't want that to be the definition of equals.
Map
A better approach is to use a different collection than Vector. One of the Map implementations makes more sense. A map stores a pair of objects, a key and a value.
In this example the dog's name string would be the key. The dog object would be the value. When you later provide the key, you can retrieve the value (the dog object). You can ask the map if it contains contains a particular key.
See the Tutorial on Map.
By the way, Vector is generally not used any more. It was long ago supplanted by other implementations of List such as ArrayList and LinkedList.
Related
I'm currently sitting at an exercise, which wants me to create a Java program based on an already finished documentation HTML sheet.
For example, one entry states
reversedArray
public static Object[] reversedArray(Object[] array)
Based on the name, we can assume the method should return an array in the reversed order of array.
Now my question isn't about how to create the said array, but more about the Object[] terminology. What does it mean? Should I create a bunch of methods through overloading each with a specific array type (e.g. String[], int[], ...) or literally an Object[]?
It's the latter, how does an object array work? Based on the name, I assume it's an array that can hold objects, but I'm unsure what this means in practice.
Object[] is basically just an array of objects (best explanation award right here please ----> ☐ )
Jokes aside, in Java, any object is derived from the class Object so basically, this array can store any object of any class. It's mostly useful when you just want to carry an instance (or several instances) of different classes, but the type of said instance is not important.
Let's say you have multiple classes that are not necessarily related :
Class Dog {
String name;
public Dog(String name) {
this.name = name
}
public String toString() {
return "Hello! I am a dog called " + this.name;
}
}
Class Refrigerator {
public Refrigerator() {
}
public String toString() {
return "I am a refrigerator";
}
}
Since both classes are implicitly derived from Object and that Object implements the method toString() you can override that method in both of you class declarations.
Then you can store any instance of these in a Object and call the method toString(), like so :
Dog myDog = new Dog("Spike");
Object anyObject = myDog;
System.out.println(anyObject.toString()); //would print the result of your "toString()" method in the Dog class :
//"Hello! I am a dog called Spike"
Refrigerator myFridge = new Refrigerator();
Object secondObject = myFridge;
System.out.println(secondObject.toString()); //would print the result of your "toString()" method in the Refrigerator class :
//"I am a refrigerator"
This allows you to create a method that accepts any object and treats them the same and assign any object in argument :
public void printWhatYouAre(Object o) {
System.out.println(o.toString());
}
public void doingSomething() {
Dog myDog = new Dog("Spike");
Refrigerator myFridge = new Refrigerator();
printWhatYouAre(myDog);
printWhatYouAre(myFridge); //would print the same as above
}
In your case, your method only needs to rearrange an array, which means it doesn't even need the method toString nor does it need to know what the objects are. It just needs to store an array of something into an other array of something in a different order.
Here is a nice reading about polymorphism in Java, which is basically applicable in any language, but the examples that are used are wrote in Java. The whole site actually is a pretty good reference, so it's worth taking a look, especially the OOP sections which are the most related to your post. ;)
As the name already states, the method should create a new array in
the reversed order of "array".
The method name only says to "reverse" the array; whether it's just a matter of modifying the actually supplied array or constructing a new one is something you'll need to clarify with the author of the requirement if it's not clear.
Now my question isn't about how to create said array, but more about
the "Object[]" terminology. Basically, I'm unsure what to do. Does
said "Object[]" mean, I should create a bunch of methods through
overloading each with a specific array type (e.g. String[], int[],...)
or literally an Object[] array?
No, you only have to create overloads for the primitive types i.e. int[], long[] etc and that's only if your requirement says so. the aforementioned method should be able to consume Object[], String[] , Integer[] , Double[] etc...
It it's the latter, how does an object array work? Based on the name I
assume, it's an array that can hold objects, but I'm unsure what this
means in practice.
The method name has nothing to do with what an array can hold, the method argument is an array of Object's and it's as simple as that.
Reading you might find useful:
Arrays
This is a simple question (I think)
Lets say I have this code (Assuming I have a dog class)
String name = "dog";
dog name = new dog();
How can I get java to recognize name as a String and name the object dog?
While you can do what you're trying in some scripting languages such as PHP (and this question is often asked by many PHP programmers who start Java), this is not how Java works, and in fact variable names are a much less important than you may realize and hardly even exist after code is compiled. What is much more important and what is key are variable references -- the ability to gain access to a particular object at a particular point in your program, and you can have Strings refer to objects easily by using a Map as one way.
For example
Map<String, Dog> dogMap = new HashMap<String, Dog>();
dogMap.put("Fido", new Dog("Fido"));
Dog myPet = dogMap.get("Fido");
Or you can gain references to objects in many other ways such as via arrays, ArrayLists, LinkedLists, or several other collectinos.
Edit
You state:
The thing is that in my code I am going to be using one method to create objects, the name of the object is arbitrary but I need it to be dynamic because it wont be temporary, so the actually name of the object has to change or I will be writing over the previously declared object.
This is exactly what I meant when I said that the name of the variable is not as important as you think it is. The variable name is not the "object name" (this really doesn't exist in fact).
For example if you create a dog in a variable named Fido, and then assign it to a new variable named spot, both variables, despite having different names will refer to the very same object:
Dog fido = new Dog;
Dog spot = fido; // now fido and spot refer to the same object
If you want to give a variable a "name" consider giving the class a name property:
class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Now you can give each Dog object its own (semi) unique name if you wish.
I don't suppose you are thinking of Enums?
private static void test () {
Animal animal = Animal.valueOf("Dog");
}
enum Animal {
Dog,
Cat,
Cow,
Pig,
Rat,
Ant,
Gnu;
}
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 6 years ago.
I have below two situations related to ArrayList get method, one with custom class and one with String class:
1. Below is the example of modifying Custom class ArrayList element:
ArrayList<MyClass> mTmpArray1 = new ArrayList<MyClass>();
MyClass myObj1 = new MyClass(10);
mTmpArray1.add(myObj1);
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
MyClass myObj3 = mTmpArray1.get(0);
Log.d(TAG, "Int Value:"+myObj3.myInt); // Prints "20"
2. And below is the example of modifying String ArrayList element:
ArrayList<String> mTmpArray2 = new ArrayList<String>();
mTmpArray2.add("Test_10");
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
String myStr2 = mTmpArray2.get(0);
Log.d(TAG, "Str Value:"+myStr2); // Prints "Test_10"
So in case of MyClass ArrayList, when I call get and modify the value, then I see change is reflecting when I do get again.
But same way when I modify String ArrayList, then changes are not reflecting.
What is the different in of the get method in both the scenarios?
Is it that in case of String, String class creating deep copy and returns new object, and in case of Custom class shallow copy is created?
In the first scenario applicable to "LinkedHashMap", "HashMap" and "List"?
Your are not doing the same thing in the two cases.
Here you update the state of an object, so the change affects the object stored in the list :
myObj2.myInt = 20;
Here you are assigning a new object to a local variable, so the list is not affected :
myStr1 = "Test_20";
If String was mutable, you could have modified the String by calling some method, and the change would have been reflected in the object stored in the list :
myStr1.setSomething(...);
On the other hand, if in the first case you would have changed the value of the local variable, the object stored in the list wouldn't have been affected :
myObj2 = new MyClass (...);
Strings are immutable. You're not inserting the new string into the array list.
When you do String myStr2 = mTmpArray2.get(0);, even tho you are pointing to a reference in the ArrayList, any attempt to change the value, will (because of String immutability) create a new String (myStr2) that will not reference the ArrayList anymore.
When you do myStr1 = "xxx", you're not actually changing the ArrayList reference, you're changing a new (copy) (now called myStr1) that was grabbed from the ArrayList and it has a local scope.
Read some more about Strings: Immutability of Strings in Java
Now in the first example, you are pointing to a mutable object (your custom class) so you're literally changing the direct value, through the reference. Welcome to Java. ;)
Unrelated: This code: MyClass myObj1 = new MyClass(10); is (arguably) considered bad. It's better to use a factory pattern that is a lot easier to read. In other words, public constructors with parameters are hard to read (for example, I have no idea what I am constructing when I read your code).
A (perhaps) better approach would be: MyClass myObj = MyClass.createInstanceWithCapacity(10); // i've invented the name because I don't know what your 10 is, but look at both, which one do you think is easier to understand upon first glance?
Disclaimer: The above unrelated comment is my personal opinion and not all developers will agree. ;)
Strings have very nice property called "Immutablity"
This means that String cannot be mutable (changed), when we create/
try to refer to old string, a new instance string is created. And any
changes we do are saved in new instance and it do not affect the old
string
For example,
String s = "Old String";
System.out.println("Old String : "+s); // output : Old String
String s2 = s;
s2 = s2.concat(" made New");
System.out.println("New String : "+s2); // output : Old String made New
System.out.println("Old String is not changed : "+s); // output : Old String
These is no difference between the two "get" calls. The difference is between the types that the ArrayList is holding, and what you're doing the references the "get" method returns.
In your first example, you do this:
MyClass myObj2 = mTmpArray1.get(0);
myObj2.myInt = 20;
Here, you're getting a reference to the MyClass instance in the ArrayList in position 0, and you are modifying a field within this instance.
In your second example, you do this:
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
Here, you're getting a reference to the String instance in the array list, and then you're giving myStr1 a reference to a different string which you create ("Test_20"). It's as if you did wrote myObj2 = new MyClass(20); in the 2nd line in the 1st example.
So, in short, in the 1st example, you access a field within the object by altering it from the reference you grabbed. In the 2nd example, you simply altered your reference to point at a different String.
I should also mention that in Java, Strings are immutable, meaning once they have been created, they cannot be changed.
String is an immutable class. A line like
myStr1 = "Test_20";
does not change the value of the String object myStr1 is pointing to. Instead a new String is created and myStr1 is modified to point to the new String. The original String is unchanged and can be retrieved from the ArrayList.
Your MyClass object is clearly mutable. Only one instance is created and its state is changed by the assignment
myObj2.myInt = 20;
Hence when this object is retrieved from the ArrayList, its new state is seen.
You simply do NOT change the list in your 2nd example.
In the first example, you are doing this:
Get the first object from the list and store it in the variable called 'myObj2'
Modify the object stored in variable 'myObj2' by setting the int value of this object
But your second example is completely different:
String myStr1 = mTmpArray2.get(0);
myStr1 = "Test_20";
Let me translate that:
Get the first element from the list and store it in the variable called 'myStr1'.
Set the value of the variable 'myStr1' to "Test_20"
So, in case one you are modifying a variable of the object stored in the list. In case two you are retrieving the object stored in the list - and then re-use the variable you stored that retrieved object in and use it for something new - but that does not change the original list, of course.
To modify your list for a type like string, you would need to use set(x, "Test_20").
This is a simple question (I think)
Lets say I have this code (Assuming I have a dog class)
String name = "dog";
dog name = new dog();
How can I get java to recognize name as a String and name the object dog?
While you can do what you're trying in some scripting languages such as PHP (and this question is often asked by many PHP programmers who start Java), this is not how Java works, and in fact variable names are a much less important than you may realize and hardly even exist after code is compiled. What is much more important and what is key are variable references -- the ability to gain access to a particular object at a particular point in your program, and you can have Strings refer to objects easily by using a Map as one way.
For example
Map<String, Dog> dogMap = new HashMap<String, Dog>();
dogMap.put("Fido", new Dog("Fido"));
Dog myPet = dogMap.get("Fido");
Or you can gain references to objects in many other ways such as via arrays, ArrayLists, LinkedLists, or several other collectinos.
Edit
You state:
The thing is that in my code I am going to be using one method to create objects, the name of the object is arbitrary but I need it to be dynamic because it wont be temporary, so the actually name of the object has to change or I will be writing over the previously declared object.
This is exactly what I meant when I said that the name of the variable is not as important as you think it is. The variable name is not the "object name" (this really doesn't exist in fact).
For example if you create a dog in a variable named Fido, and then assign it to a new variable named spot, both variables, despite having different names will refer to the very same object:
Dog fido = new Dog;
Dog spot = fido; // now fido and spot refer to the same object
If you want to give a variable a "name" consider giving the class a name property:
class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Now you can give each Dog object its own (semi) unique name if you wish.
I don't suppose you are thinking of Enums?
private static void test () {
Animal animal = Animal.valueOf("Dog");
}
enum Animal {
Dog,
Cat,
Cow,
Pig,
Rat,
Ant,
Gnu;
}
String abc[]={"abc"};
String def[]={};
def=abc;
def[0]=def[0]+"changed";
System.out.println(abc[0]);
by changing "def" object, my abc object is changed as well. Beside String[] array has this characteristic what other java object has similar characteristic? can explain more? in order to prevent abc from changed when i changed def, i will have to do def = abc.clone();
You are confusing object mutability/immutability with copying of reference values.
In these diagrams, [var/index] is a reference variable, and {{an Object}} is an object.
String abc[]={"abc"};
String def[]={};
[abc] ------> {{a String[1]}}
[0] --------------> {{a String "abc"}}
[def] ------> {{a String[0]}}
Now you make def reference variable points to the same object as abc reference variable:
def=abc;
[abc] ------> {{a String[1]}}
/ [0] --------------> {{a String "abc"}}
/
[def] ---/ {{a String[0]}}
At this point, the array of length zero is unreferenced, and should be garbage-collectable. We can narrow our discussion to the array of length one. Note that a String[] is an array of references. With this next line, you changed what the only element in the length one array points to.
def[0]=def[0]+"changed";
[abc] ------> {{a String[1]}}
/ [0] ---------\ {{a String "abc"}}
/ \
[def] ---/ \--> {{a String "abcchanged"}}
Note that {{a String "abc"}} itself was not mutated. [abc] and [def] now points to the same {{a String[1]}}, which is mutable (i.e. you can make the elements of the array, which are references to String objects, to point to anything).
in order to prevent abc from changed when i changed def, i will have to do def = abc.clone();
Actually, that's not quite accurate. Let's see what happens if you clone() an array of references to a mutable type StringBuilder.
StringBuilder[] abc = new StringBuilder[] { new StringBuilder("Hello") };
StringBuilder[] def = abc.clone();
def[0].append(" world!");
System.out.println(abc[0]); // prints "Hello world!"
I won't make the diagrams for you this time, but you can easily draw it out on paper. What's happening here is that even though clone() makes a second {{a StringBuilder[1]}} object with its own element (i.e. def != abc), that element is pointing to the same {{a StringBuilder}} object (i.e. def[0] == abc[0]).
In short:
Immutability means that objects of a certain type can not change in any meaningful way to outside observers
Integer, String, etc are immutable
Generally all value types should be
Array objects are mutable
It may be an array of references to immutable types, but the array itself is mutable
Meaning you can set those references to anything you want
Also true for array of primitives
An immutable array will not be practical
References to objects can be shared
If the object is mutable, mutation will be seen through all these references
If you want more in-depth understanding of the issues, I recommend the following:
Is Java pass by reference? -- NO!
Are Java function parameters always passed-by-value? -- YES!
Immutable objects are objects that cannot be changed once created. String is an obvious example. Arrays are mutable. If you want an immutable collection, use a List instead:
List<String> abc = Collections.unmodifiableList(
Arrays.asList("abc")
);
Mutable objects have mutators. A mutator is any method that modifies the state of the object. Setters are an obvious example. A typical immutable object will look like this:
public class Person {
private final String firstName;
private final String lastName;
private final Date dateOfBirth;
public Person(String firstName, String lastName, Date dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = new Date(dateOfBirth.getTime());
}
public String getFirstName() { return firstName; }
public String getLastname() { return lastName; }
public Date getDateOfBirth() { return new Date(dateOfBirth.getTime()); }
}
Generally speaking, for immutable objects, all members are final and immutable. Date is a good example of the issue above. Date is not immutable, which many (myself included) consider a design mistake. As a result of it being mutable you have to do lots of defensive copying.
just to be pedantic, there's no "abc" object or "def" object. There's the single String[] that abc, and then def happen to refer to. That's why "both objects" changed. They were, in fact, referring to the same object.
In simple terms it is like this :-
Lets assume Sample to be a class then,
Sample sam1 = new Sample();
will clearly be explained as sam1 being the reference to the object created.
but
Sample sam2;
just declares sam2 to be a reference variable of Sample type and has no object of Sample class being pointed by it.
now if we do this operation
sam2 = sam1;
then it means both the reference variables point to the same object and now one can refer to that object using any one of the two references.
Obviously one can manipulate the fields employing the valid methods using either of the references.
And this is what has been done here too.
String abc[]={"abc"};
String def[]={};
def=abc;
def[0]=def[0]+"changed";
and so changing def[0] changes abc[0] too.
Now when you clone you are creating a clone of the existent object.
The clone and the cloned objects independently exist
as 2 different objects and so the result of manipulations on one
is not reflected as you stated.
In java, you can always change the elements in an array, regardless of the type of the array. Consider making a separate copy of the data in order to protect the initial value of abc if you would like to keep the data in an array structure:
String abc[]={"abc"};
String def[];
def = Arrays.copyOf(abc, abc.length);
Alternatively, use cletus solution:
List abc = Collections.unmodifiableList(
Arrays.asList("abc")
);