ArrayList<String> constraints_list=new ArrayList<String>();
public void setConstraints(ArrayList<String> c)
{
c = constraints_list;
constr = true;
}
i want to make ArrayList c to be ArrayList constraint_list...
how to do that?
It's not totally clear to me what you want to do. However, object references are passed by value in Java, so setting the value of c (as in your code) won't work. The typical way to set c from an instance variable is to write a getter rather than a setter:
public ArrayList<String> getConstraints() {
return constraints_list;
}
You can then say:
ArrayList<String> c = getConstraints();
If on the other hand, you are trying to do the opposite (set constraints_list from the passed in parameter), then your assignment is the wrong way round:
public void setConstraints(ArrayList<String> c) {
constraints_list = c;
constr = true;
}
You should also consider whether it's better to make a copy of the list, in which case you could do:
public void setConstraints(ArrayList<String> c) {
constraints_list = new ArrayList<String>(c);
constr = true;
}
Related
This was a question on an exam. Luckily I picked the right answer, but I still can't see why it's right.
Consider this program:
class D {
protected C c;
public D(C c) {
this.c = new C(c);
}
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
class C {
protected String s;
public C(String s) {
this.s = s;
}
public C(C c) {
this(c.s);
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public static void main(String[] args) {
C c1 = new C("1");
C c2 = new C("2");
D[] d = {
new D(c1), new D(c1), new D(c2), new D(c2)
};
d[0] = d[3];
c1.setS("3");
String r = "";
for (D i: d) {
r += i.getC().getS();
}
System.out.println(r);
}
}
It'll print 2122. I would expect 2322 however (I'm clearly wrong when you run the code). My reasoning behind that:
In the third line of the main method, four instances of D get initialized.
The constructor of D makes a new instance of C. An instance of C has a String variable which points somewhere to a spot in the memory. Now the instance variable c, let's call it c3, of the object in d[1] has a instance variable (type String), let's call it s3, pointing to the same memory as the String s1, variable of c1.
So when we change s1, I'd expect the value of s3 also to change, since it's pointing to the same spot in the memory.
On a side note, if you change the constructor of D, see below, you'll get 2322 instead. Which I'd expect, since now the variable c3 in d[1] is pointing directly towards the memory location of c1.
public D(C c) {
this.c = c;
}
My thoughts so far on the explanation (could be wrong):
When initializing the instance variable s1/s3, new String objects get made (so far I assumed they were pointing towards "1" in the String pool, since the constructor of C makes it look that way)
When changing s1, it's pointer will be redirected towards "3" in the String pool. Rather than "1" becoming "3" in the pool.
Could anyone explain this behaviour? What are the errors in my (faulty) reasoning?
This is not related to String pooling at all. Main answer: Is Java "pass-by-reference" or "pass-by-value"?
That's because D creates a new instance of C based on C#c. This mean that the instance of D#c is not the same instance as parameter C passed in constructor D, thus modifying that instance won't affect the current instance in D#c.
Re explaining all this in nice terms.
Here's what you're testing:
class Surprise {
String item;
public Surprise(String item) {
this.item = item;
}
//this is called copy constructor
//because you receive an object from the same class
//and copy the values of the fields into the current instance
//this way you can have a "copy" of the object sent as parameter
//and these two object references are not tied by any mean
public Surprise(Surprise another) {
//here you just copy the value of the object reference of another#item
//into this#item
this.item = another.item;
}
}
class Box {
Surprise surprise;
public Box(Surprise surprise) {
//here you create a totally new instance of Surprise
//that is not tied to the parameter surprise by any mean
this.surprise = new Surprise(surprise);
}
public static void main(String[] args) {
Surprise surprise1 = new Surprise("1");
Surprise surprise2 = new Surprise("2");
Box[] boxes = {
new Box(surprise1),
new Box(surprise1),
new Box(surprise2),
new Box(surprise2)
};
boxes[0] = boxes[3];
//you update surprise1 state
//but the state of Box#surprise in the boxes that used surprise1
//won't get affected because it is not the same object reference
surprise1.item = "3";
//print everything...
System.out.println("Boxes full of surprises");
//this code does the same as the printing above
for (Box box : boxes) {
System.out.print(box.surprise.item);
}
System.out.println();
}
}
R call java interface issues.
I knew how to new a java user defined class object as well as call java function in R, some return values can be used directly in R, like integer, string, array, but I have no idea how to access the values of arraylist object.
For example:
public class Bond
{
public String compName;
public long mfAmt;
public Bond() {
}
}
public class test_arr
{
public test_arr()
{
}
public ArrayList<Bond> getArrListDef()
{
ArrayList<Bond> arr = new ArrayList();
Bond bond = new Bond();
bond.compName = "app";
bond.mfAmt = 12;
arr.add(bond);
return arr;
}
public ArrayList<Bond> getArrList(ArrayList<Bond> arr)
{
return arr;
}
}
R call java part:
library(rJava)
test_arr = J('pkg.test_arr')
jarr = test_arr$getArrListDef()
now, the variable jarr is a Java-Object{}, so how can I print the value of jarr in R...also, how to passing a java arraylist object to another function "public ArrayList getArrList(ArrayList arr)".
You can always use the $ convenience operator. It provides an experimental, but simple way of writing code in Java style at the cost of speed. For example to print all elements mfAmt
for (index in seq(test_arr$size())-1)
print(test_arr$get(as.integer(index))$mfAmt)
This is more of a logical question than code specific, I have some twenty functions, each function calculates two values of my interest. However I can only return one value from a function. Now the other option I have is to make a class and implement setter and getter with global variables. I want to know if this is a feasible and recommended way? Or there is a better way to do this?
Don't use global variables! Use some class that has your data as private fileds, and provide getters for it. Like in
class Pair<A,B> {
final A one;
final B two;
public Pair(A fst, B snd) { one = fst; two = snd; }
public A getFst() { return one; }
public B getSnd() { return two; }
}
Then you can elsewhere say something like:
return new Pair(42, "a result");
Return a Collection from your function containing your values of interest.
Depends on the problem. But 2 solutions are :
Make new class which instances will be returned by all this functions. This class would have 2 attributes for each needed answer.
Return array or Collection with this 2 answers.
You have to return a List or a array.
But if return types are different you can create custom class and use it as return type.
Example
public class Result {
private String name;
private int age;
// getters and setters;
}
Now you can have some thing like following
public static Result getInfo(){
Result result=new Result();
result.setName("name");
result.setAge(10);
return result;//now you can have String and int values return from the method
}
There are many ways: collections, arrays ...
In my opinion the only way is to define a class with these values.
you do not need getter and setter methods if you don't need to regulate the visibility of the contents
class MyReturnValue {
public int a;
public int b;
}
in your code:
...
MyReturnValue result=new MyReturnValue();
result.a=5;
result.b=6;
return result;
It is better to make a class and implement setter and getter with global variables rather than to Return Collection further it depends on your use.
You can do this
long[] function() {
long[] ret = { a, b };
return ret;
}
or
long[] a = { 0 }, b = { 0 };
void function(long[] a, long[] b) {
a[0] = ...
b[0] = ...
or add properties to an object.
private long a,b;
void function() {
a = ...
b = ...
}
in the last case you can value.
class Results {
public final long a;
public final Date b; // note: Date is not immutable.
// add constructor
}
public Results function() {
long a = ...
Date b = ...
return new Results(a, b);
}
I think making a Record class is the most suitable.
public class Record {
public final int a;
public final int b;
public Record(final int a, final int b) {
this.a = a;
this.b = b;
}
}
Then your functions can return type Record, and you can access it with let's say record.a and record.b.
This is also one of the few cases where public variables and no getters and setters can be justified.
UPDATE: Implemented a proposed change, now everything is final, which means that Record cannot be modified when you get it back, which seems to be in line with expectations. You only want the results and use those.
What about adopting varargs with generic helper function for getting around of number of returning variable limitation: In this solution, we won't have to declare a new class every time when number of returning variable changes.
class Results
{
private final Object[] returnedObj;
public Results(Object... returnedObj)
{
this.returnedObj = returnedObj;
}
public <E> E getResult(int index)
{
return (E)returnedObj[index];
}
}
Test case:
public static Results Test()
{
return new Results(12, "ABCD EFG", 12.45);
// or return larger number of value
}
//// And then returning the result
Results result = Test();
String x = result.<String>getResult(1);
System.out.println(x); // prints "ABCD EFG"
You could even return the values separated by a special character say a "~" if you are sure that the "~" won't appear in your results.
Suppose I have an array int[][] or an array char[][] or an ArrayList. Is there a way in java to know the base class type of the array. For Example:
int[][] gives output as int.
char[][] gives output as char.
ArrayList<Integer> gives output Integer.
ArrayList<Point> gives Point. (It should also work for a custom type)
Can this be done in Java?
Arrays (e.g. int[][])
You can get the array's component type using getComponentType():
(new int[10][10]).getClass().getComponentType().getComponentType(); // int
For arrays of arbitrary depth use a loop:
Object array = new int[10][][][];
Class<?> type = array.getClass();
while (type.isArray())
{
type = type.getComponentType();
}
assert type == Integer.TYPE;
Generic Types (e.g. ArrayList<Integer>)
It is not possible to get the type parameter. Java uses type erasure, so the information is lost at runtime.
You can guess the declared type of collections based on the types of the elements:
import java.util.*;
public class CollectionTypeGuesser
{
static Set<Class<?>> supers(Class<?> c)
{
if (c == null) return new HashSet<Class<?>>();
Set<Class<?>> s = supers(c.getSuperclass());
s.add(c);
return s;
}
static Class<?> lowestCommonSuper(Class<?> a, Class<?> b)
{
Set<Class<?>> aSupers = supers(a);
while (!aSupers.contains(b))
{
b = b.getSuperclass();
}
return b;
}
static Class<?> guessElementType(Collection<?> collection)
{
Class<?> guess = null;
for (Object o : collection)
{
if (o != null)
{
if (guess == null)
{
guess = o.getClass();
}
else if (guess != o.getClass())
{
guess = lowestCommonSuper(guess, o.getClass());
}
}
}
return guess;
}
static class C1 { }
static class C2 extends C1 { }
static class C3A extends C2 { }
static class C3B extends C2 { }
public static void main(String[] args)
{
ArrayList<Integer> listOfInt = new ArrayList<Integer>();
System.out.println(guessElementType(listOfInt)); // null
listOfInt.add(42);
System.out.println(guessElementType(listOfInt)); // Integer
ArrayList<C1> listOfC1 = new ArrayList<C1>();
listOfC1.add(new C3A());
System.out.println(guessElementType(listOfC1)); // C3A
listOfC1.add(new C3B());
System.out.println(guessElementType(listOfC1)); // C2
listOfC1.add(new C1());
System.out.println(guessElementType(listOfC1)); // C1
}
}
You could use the classes getComponentType(). For example.
public static final Class<?> getBaseType(Object obj) {
Class<?> type = obj.getClass();
while (type.isArray()) {
type = type.getComponentType();
}
return type;
}
type will then be whatever the base type is.
This will work if obj is double[][][][][][] or just double[], or something else.
As for generics, those things in < and >. Type erasure occurs, meaning you cannot determine what type those are from the ArrayList itself.
In case of arrays, it can be identified via the type of an array, (e.g. array of int[][] will always give you int.
In case of ArrayList, if your ArrayList is heterogeneous objects then, get(i) will always give you the element of type Object. To know its class, you can use getClass() method of Object.
Following code works...as you asked..
Here, I have used
object.getClass().getSimpleName()
for arraylist you must add an item of specific type since you are using generics. and then get them and have it use same getClass().getSimpleName() method.
public class ShowObjectType {
public static void main(String[] args) {
int arr[][] = { { 2, 3 }, { 4, 0 } };
char[][] arr1 = { { 'a', 'c' }, { 'b', 'd' } };
ArrayList<Integer> arr2 = new ArrayList<Integer>();
arr2.add(4);
ArrayList<Point> arr3 = new ArrayList<Point>();
arr3.add(new Point());
System.out.println(arr.getClass().getSimpleName());
System.out.println(arr1.getClass().getSimpleName());
System.out.println(arr2.get(0).getClass().getSimpleName());
System.out.println(arr3.get(0).getClass().getSimpleName());
}
}
class Point {
}
hope it helps
Yes, those are called Generics. But is better to think that it forces the Arraylist to only hold "point" objects.
Two ways to do this:
Use the instanceof operator.
Call getClass() on the object (make sure to check for null first).
For this you can also refer which i found:
http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
You can get base type of Array as:
Object obj = new Long[0];
Class ofArray = obj.getClass().getComponentType();
For Collection type, you can use the getClass() method, or you can use instanceof. For example:
ArrayList<Object> list = ...;
for (Object obj : list) {
if (obj instanceof String) {
...
}
}
for (Object o : list) {
if (o.getClass().equals(Integer.TYPE)) {
handleInt((int)o);
}
else if (o.getClass().equals(String.class)) {
handleString((String)o);
}
...
}
For primitive types you can use this code:
public static void main(String[] args) {
int arr[] = {1,2,3};
int arr2[][] = {{1},{2},{3}};
char arrc[] = {'v', 'c', 'r'};
System.out.println(arr.getClass().getCanonicalName());
System.out.println(arr2.getClass().getCanonicalName());
System.out.println(arrc.getClass().getCanonicalName());
}
the output is:
int[]
int[][]
char[]
For ArrayList if you need to work with its elements (if list is not empty) you may check the type of the first element
ArrayList<Integer> arrInt = new ArrayList<Integer>();
arrInt.add(100);
if (arrInt instanceof List && arrInt.size() > 0) {
System.out.println(arrInt.get(0).getClass().getCanonicalName());
}
What is a copy constructor?
Can someone share a small example that can be helpful to understand along with defensive copying principle?
Here's a good example:
class Point {
final int x;
final int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
Point(Point p) {
this(p.x, p.y);
}
}
Note how the constructor Point(Point p) takes a Point and makes a copy of it - that's a copy constructor.
This is a defensive copy because the original Point is protected from change by taking a copy of it.
So now:
// A simple point.
Point p1 = new Point(3,42);
// A new point at the same place as p1 but a completely different object.
Point p2 = new Point(p1);
Note that this is not necessarily the correct way of creating objects. It is, however, a good way of creating objects that ensures that you never have two references to the same object by accident. Clearly this is only a good thing if that is what you want to achieve.
Copy constructors one often sees in C++ where they are needed for partly hidden, automatically invoked operations.
java java.awt.Point and Rectangle come to mind; also very old, mutable objects.
By using immutable objects, like String, or BigDecimal, simply assigning the object reference will do. In fact, due to the early phase of Java after C++, there still is a
silly copy constructor in String:
public class Recipe {
List<Ingredient> ingredients;
public Recipe() {
ingredients = new ArrayList<Ingredient>();
}
/** Copy constructor */
public Recipe(Recipe other) {
// Not sharing: ingredients = other.ingredients;
ingredients = new ArrayList<>(other.ingredients);
}
public List<Ingredient> getIngredients() {
// Defensive copy, so others cannot change this instance.
return new ArrayList<Ingredient>(ingredients);
// Often could do:
// return Collections.immutableList(ingredients);
}
}
On request
Leaking class with copy constructor:
public class Wrong {
private final List<String> list;
public Wrong(List<String> list) {
this.list = list; // Error: now shares list object with caller.
}
/** Copy constructor */
public Wrong(Wrong wrong) {
this.list = wrong.list; // Error: now shares list object with caller.
}
public List<String> getList() {
return list; // Error: now shares list object with caller.
}
public void clear() {
list.clear();
}
}
Correct class with copy constructor:
public class Right {
private final List<String> list;
public Right(List<String> list) {
this.list = new ArrayList<>(list);
}
public Right(Right right) {
this.list = new ArrayList<>(right.list);
}
public List<String> getList() {
return new ArrayList<>(list);
}
public List<String> getListForReading() {
return Collections.unmodifiableList(list);
}
public void clear() {
list.clear();
}
}
With testing code:
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "a", "b", "c", "d", "e");
Wrong w1 = new Wrong(list1);
list1.remove(0);
System.out.printf("The first element of w1 is %s.%n", w1.getList().get(0)); // "b"
Wrong w2 = new Wrong(w1);
w2.clear();
System.out.printf("Size of list1 %d, w1 %d, w2 %d.%n",
list1.size(), w1.getList().size(), w2.getList().size());
List<String> list2 = new ArrayList<>();
Collections.addAll(list2, "a", "b", "c", "d", "e");
Right r1 = new Right(list2);
list2.remove(0);
System.out.printf("The first element of r1 is %s.%n", r1.getList().get(0)); // "a"
Right r2 = new Right(r1);
r2.clear();
System.out.printf("Size of list2 %d, r1 %d, r2 %d.%n",
list2.size(), r1.getList().size(), r2.getList().size());
}
Which gives:
The first element of w1 is b.
Size of list1 0, w1 0, w2 0.
The first element of r1 is a.
Size of list2 4, r1 5, r2 0.
Copy constructor in java can be used when you need to clone an object
class Copy {
int a;
int b;
public Copy(Copy c1) {
a=c1.a;
b=c1.b;
}
}
In java when you give Copy c2=c1; simply creates a reference to the original object and not the copy so you need to manually copy the object values.
See this:
Why doesn't Java have a copy constructor?
Copy Constructor in Java
This is where you create a new object, by passing an old object, copying its values.
Color copiedColor = new Color(oldColor);
instead of :
Color copiedColor = new Color(oldColor.getRed(),
oldColor.getGreen(), oldColor.getBlue());
A copy constructor is used to create a new object using the values of an existing object.
One possible use case is to protect original object from being modified while the copied object can be used to work upon.
public class Person
{
private String name;
private int age;
private int height;
/**
* Copy constructor which creates a Person object identical to p.
*/
public person(Person p)
{
person = p.person;
age = p.age;
height = p.height;
}
.
.
.
}
Related to defensive copy here is a good read