Curly Bracket Initialization in C++ and Java - java

In the code below, I don't seem to understand the limitations of the curly bracket initialisation. What do they actually do? It seems in the case of A it just sets a[0] equal to the value directly. In the case of b it using implicit conversion. Does it decide which one to do based on what is available, or is there some other method it uses?
#include <iostream>
using namespace std;
struct A
{
};
struct B
{
B(int a) { cout << a; }
};
int main()
{
A* a[] = {new A()};
B b[] = {1};
}
Also would this type of curly bracket initialisation work similarly in Java?
public class A
{
public static void main(String[] args)
{
someClass[] sC = { /* what can go here? an argument to the constructor,
or just a value to set the variable equal to */ }.
}
}
Sorry if my question seems silly, just really want to know more about curly brackets in c++ and Java. Thanks in advance :-)

Since the Java part has already been answered, I will add a bit about the C++ part. The specific version of curly brace initialization that you refer to is called aggregate initialization and (unsurprisingly) is used to initialize aggregates. Each element in the aggregate will be initialized with the corresponding element inside the braces and you can use whatever you want to use that can be implicitly convertible to the type of the element in the aggregate.
There are a couple of specific parts of the feature that you might want to consider for the specific case of arrays. The number of elements inside the curly braces cannot be greater than the size of the array, but it can be smaller in which case the rest of the elements will be default initialized.
int a[5] = { 1, 2 }; // [ 1, 2, 0, 0, 0 ]
If the size of the array is not provided in user code, the compiler will set it to the number of elements in the aggregate-initialization list:
int a[] = { 1, 2, 3 }; // int a[3]
Note that unlike in Java, the size is an integral part of the type of the array, so that while you can type int a[] = { 1 };, it can never be a generic array of undetermined number of int.
In C++11 the curly brace syntax has been extended to provide uniform initialization, but that is probably outside of the scope of the question, I just mention it in case you want to read more on the subject.

It's the same thing as in C++
someClass[] sC = { new someClass(), new someClass(), new someClass() };
int[] i = { 1, 2, 3 };
String[] s = { "1", "2", "3" };

I don't quite remember how it is done in C++, but in java you can do:
String[] array = new String[]{ "a", "b", "c" };
So you don't pass arguments to the constructors, you pass the objects themselves.

In Java, array is a container object.
You can store values for primitive types and object references of someClass or its sub-classes into array of someClass[] sC.
class SomeClass {}
class Foo extends SomeClass{}
Foo f=new Foo();
SomeClass []sC={f,new Foo(),new SomeClass()};

Related

How to define multiple variables in single statement

In Python, I can define two variables with an array in one line.
>>>[a,b] = [1,2]
>>>a
1
>>>b
2
How do I do the same thing in Java?
I have a couple of variables in class PCT which type is final. Is there a way to define them in one line in a Python like fashion? The following format clearly does not work in Java. I could define them separately, but it will call the parseFile method twice which I want to avoid.
public class PCT {
final int start;
final int stop;
public PCT (File file) {
//......
//......
// the following statement does not compile
[start, stop] = parseFile(file);
}
public int[] parseFile(File f) {
int[] aa = new int[2];
// ....
// ....
return aa;
}
}
You can define multiple variables like this :
double a,b,c;
Each variable in one line can also be assigned to specific value too:
double a=3, b=5.2, c=3.5/3.5;
One more aspect is, while you are preparing common type variable in same line then from right assigned variables you can assign variable on left, for instance :
int a = 4, b = a+1, c=b*b;
Noticed, you can also practice arithmetic operations on variable by remaining in the same line.
This is not possible, but you also don't need to call parseFile twice.
Write your code like this:
int [] temp = parseFile(file);
start = temp[0];
stop = temp[1];
Python (I believe) supports multiple return values. Java obeys C conventions, and so doesn't permit it. Since that isn't part of the language, the syntax for it isn't either, meaning slightly gross hacks like the temp array are needed if you're doing multiple returns.
When declaring several variables of the same type, you can do the following:
int a = 1, b = 2, c = 3; //etc.
If you literaly mean line; as long as you place a semicolon in between two statements, they are executed as if there is a new line in between so you can call:
a = 1; b = 2;
You can even compress an entire file into a oneliner, by removing comment (that scope to the end of the line). Spacing (space, tab, new line,...) is in general removed from the Java files (in memory) as first step in the Java compiler.
But you are probably more interested in a singe statement. Sytax like [start, stop] = parseFile(file); is not supported (at least not for now). You can make a onliner:
int[] data = parseFile(file); start = data[0]; stop = data[1];
Maybe this is what you're looking for:
int array[] = {1,2};
Java array assignment (multiple values)
If you're looking to explicitly assign to each element, I don't think you can do that within one assignment, as a similar concept with the 2-d example below. Which seems like what you want as Jeremy's answers specifies.
Explicitly assigning values to a 2D Array?
Maybe
public class PCT
{
final Point pos; // two ints!
public PCT (File file)
{
pos = parseFile(file);
}
public int[] parseFile(File f)
{
Point aa = new Point();
// ....
// ....
return aa;
}
}

Why can't we just use arrays instead of varargs?

I just came across varargs while learning android(doInBackground(Type... params)) ,SO posts clarified the use of it
My question is why can't we just use Arrays instead of varargs
public void foo(String...strings) { }
I can replace this type of a call by packing my variable number of arguments in an array and passing it to a method such as this
public void foo(String[] alternativeWay){ }
Also does main(String[] args) in java use varargs , if not how are we able to pass runtime parameters to it
Please suggest the benefits or use of varargs and is there there anything else important to know about varargs
The only difference between
foo(String... strings)
and
foo(String[] strings)
is for the calling code. Consider this call:
foo("a", "b");
That's valid with the first declaration of foo, and the compiler will emit code to create an array containing references to "a" and "b" at execution time. It's not valid with the second declaration of foo though, because that doesn't use varargs.
In either case, it's fine for the caller to explicitly create the array:
for(new String[] { "a", "b" }); // Valid for either declaration
Also does main(String[] args) in java use varargs , if not how are we able to pass runtime parameters to it
When it's written as main(String[] args) it doesn't; if you write main(String... args) then it does. It's irrelevant to how the JVM treats it though, because the JVM initialization creates an array with the command line arguments. It would only make a difference if you were writing your own code to invoke main explicitly.
We could use arrays instead of varargs. Varargs are syntactic sugar for using arrays. But they make your code more compact and more readable. Compare
private void foo(String... ss) { ... }
private void bar() {
...
foo("One", "Two", "Three");
...
}
with
private void foo(String[] ss) { ... }
private bar() {
...
foo(new String[] { "One", "Two", "Three" });
...
}
Similarly, we don't need the diamond operator (<>, Java 7) or lambdas (Java 8) either. But they do make code more readable and therefore more maintainable.
One advantage of varargs is for methods requiring at least one parameter, such as max. With varargs you can do it like this
static int max(int first, int... remaining) {
int max = first;
for (int number : remaining)
max = Math.max(max, number);
return max;
}
This is great, because it is impossible to pass no parameters to the max method, and the calling code for max is really clean: max(2, 4, 1, 8, 9). Without varargs the only way to have enforced the condition that at least one number should be passed would have been to have thrown an exception at runtime if the array had length 0 (always best avoided) or to force the caller to write max(2, new int[] {4, 1, 8, 9}) which is really ugly.
Because you function call looks more like a function call, ex.:
new MyAsyncTask().execute("str1", "str2");
looks better than:
new MyAsyncTask().execute(new String[]{"str1", "str2"});
There is no magic behind AsyncTask, very often you dont really need to pass any parameters, sometimes you pass parameters to constructor instead of execute. There are also implementations of AsyncTask :
https://github.com/roboguice/roboguice/blob/master/roboguice/src/main/java/roboguice/util/SafeAsyncTask.java
that dont use varargs at all

Set array method on java

I have a class arrayFun with the variable
int[] _array;
I have a method setArray:
public void setArray(int [] array)
{
_array = array;
}
Is my set method implementation correct ?
2).How can I use this method in other class with main ?
I've tried some ridiculous options like:
arrayFun A = new arrayFun(some_constructor_values);
A.setArray(1,2,3,4,5);
That option of course doesn't work...
Try
A.setArray(new int[]{1,2,3,4,5});
Another way to solve this declare the argument as a "varargs" argument as follows:
public void setArray(int ... array) {
_array = array;
}
and then this will work:
A.setArray(1, 2, 3, 4, 5);
You can do the same with a constructor argument.
While I have your attention, it is important that you learn the Java naming conventions, and learn to follow them strictly.
A class name should always start with an uppercase letter
A variable name should always start with a lowercase letter ... unless it is a static final constant.
Using an underscore as a prefix generally frowned on.
For more information, read the Java Style Guidelines.
So your example class should look like this:
public class ArrayFun {
private int[] array;
public void setArray(int ... array) {
this.array = array;
}
}
and should be used like this:
ArrayFun a = new ArrayFun();
a.setArray(1, 2, 3, 4, 5);
You can use this instead
public void setArray(int... array) { _array = array; }
// later
ArrayFun a = new ArrayFun(some_constructor_values);
a.setArray(1,2,3,4,5);
Unless you take a copy of the array, you will be using the same array in the caller and callee.
What you're asking to do doesn't really make sense. Also, why use a function to "set the array", why not just set the array directly:
_array = newArray
You can also set an array's values like this:
int[] array = {1,2,3,4,5};
Your method's signature is :
public void setArray(int[] array)
So it accepts only one argument that is of type array of integers.
But in your method call, you are calling it as:
A.setArray(1,2,3,4,5);
In this you are passing 5 arguments to the method. So it does not match any method with 5 arguments. Thats why it does not work.
You should pass one array of integers.
You can do it in various ways :
int myArr[] = {1,2,3,4,5};
A.setArray(myArr);
or
A.setArray(new int[]new int[]{1,2,3,4,5});
Setting array the way you did is fine. But what you are setting from A.setArray(1,2,3,4,5); will throw you error saying "Method setArray(int,int,int,int,int) is not found".
You can do something like int[] ar = { 1, 2 };
a.setArray(ar);

Java: Generic Static Multidimensional Arrays

If it is possible, how can I create a static multidimensional array in Java with different primitive datatypes per dimension?
By static, I mean the primitive array that is not dynamic like an ArrayList would be.
You can't.
A multidimensional array is, by definition, an array of arrays of arrays .... of something. So there's no way for any of those dimensions except the last to be anything other than an array. At least, by the traditional definition anyway. But if you mean something else by "multidimensional array", you'll need to tell us what that is.
As for "static", that is a heavily overloaded word in programming and every language that I can think of uses it to mean something slightly different. In Java, static means "belongs to a class, rather than to instances of that class." Again, if you mean something else by "static" here, you'll need to tell us what that is.
Edit: As originally posted, the question didn't include the word "primitive". That changes it a bit. Indeed, I agree that it would be nice from a convenience standpoint if Java allowed arrays to be indexed by char or even an enum rather than just int. But it doesn't.
Dimensions in an Array are always from type int. Think about it!
int a = 4;
int b = 5;
Shoe shoe = new Shoe (Color.RED, 42, "Leather");
Hat hat = new Hat (17, Color.Black);
Foo foo = foos[a][b];
Zilch pop = bars[shoe][hat]; // no go
If you have a multidimensional array of Foos, the first dimension is an Foo, the second an array of Foos, the third an array of array of Foo. The only variable type is the one at the bottom.
Edit after update of question:
Arrays aren't called static or primitive. Their size is fixed on initialization, and what they have in common with primitives is, that they are a buildin, which is threated special in some cases. They are - in contrast to the so called primitive types, which aren't that primitive (they have, for example, operators, exclusively for their own, like * / -) but meanwhile they are objects, but not declared in the library.
Call them build in-types.
Using Bhesh Gurung's trick:
Object[] arr = {new Integer[]{}, new String[]{}, new Double[]{}};
is begging for trouble, and it is not made of different datatypes per dimension. Let's start with the dimensions:
// One-dimensional object:
JPanel [] panels = new JPanel [3];
// Two-dimensional object:
JPanel [][] panels = new JPanel [3][10];
You have JPanels on the bottom level, and an Array of JPanel on the next dimension. You can add more dimension, and will always get an additional (Array of ...) wrapped around.
You can not mix different datatypes in an Array like int and char, or JPanel and JFrame, or int and JButton. Only if you abstract over the difference, and use an JComponent for JPanel and JFrame as common parent, but this will not work for the build-in types int, char, boolean and so on, because they aren't objects.
But can't you use autoboxing, and use Integer instead of int, Character instead of char, and then use Object as common parent class? Yes, you could, but then you're not using the primitives any more, and you're begging for troubles.
Dan is talking about a different thing - using differnt types for indexing in the multi-dimensional array:
byte b = 120;
short s = 1000;
String o [][] = new String[b][s];
b = 7;
s = 9;
o[b][s] = "foobar";
String foo = o[b][s];
There is no problem using bytes or shorts, but you can't restrict the size of an Array by declaring it as byte or short. In most cases the boundaries of a build-in integer type will not fit to a datatype (think 365 days per year), especially, since all types might get negative, so bounds-checking is necessary although and can't be restricted to compile time.
But now to the trouble:
We could declare the array as two-dimensional from the beginning:
Object[][] ar2 = {
new Integer [] {4, 5, 6},
new String [] {"me", "and", "you"},
new Character [] {'x', 'y', 'z'}};
That works fine, and makes the inner arrays accessible immediately without casting. But it is only known for the compiler, that the elements are Object arrays - the underlying type is abstracted away, and so we can write:
ar2[1][1] = 17; // expected: String
ar2[2][0] = "double you"; // expected: Char
This will compile flawlessly, but you're shooting yourself in the foot and get a Runtime exception for free.
Here is the source as a whole:
public class ArrOfMixedArr
{
public static void main (String args[])
{
Object[] arr = {
new Integer [] {1, 2, 3},
new String [] {"you", "and", "me"},
new Character [] {'a', 'b', 'c'}};
show (arr);
byte b = 7;
short s = 9;
String o [][] = new String[200][1000];
o[b][s] = "foobar";
String foo = o[b][s];
Object[][] ar2 = {
new Integer [] {4, 5, 6},
new String [] {"me", "and", "you"},
new Character [] {'x', 'y', 'z'}};
show (ar2);
// exeptions:
ar2[1][1] = 17; // expected: String
ar2[2][0] = "double you"; // expected: Char
}
public static void show (Object[] arr)
{
for (Object o : arr)
{
if (o instanceof Object[])
show ((Object[]) o);
else
System.out.print (o.toString () + "\t");
}
System.out.println ();
}
}
Now what is the solution?
If your base-types arrays of (int, byte, char, String, JPanel, ...) are of equal length, then you have something like a hidden Object, a database-row. Use a class instead:
class Shoe {
byte size;
String manufactor;
java.math.BigDecimal price;
java.awt.Color color;
}
Shoe [] shoes = new Shoe [7];
If you don't have different types of the same size, they might be unrelated, and should not be put in a common container.
After some testing, I have a simple solution:
Object [][] array = new Object [10][2];
array[0][0] = 2;
array[0][1] = false;
Well, you could define an array of an array of ... an array of Objects (nested with as many levels as dimensions) and at the bottom level fill each array with a different type ... and then, when you need to extract a value, cast it to the appropriate type. Too much work for what is worth, really. Java is no good for this kind of things, being a statically-typed language.
Maybe you should reconsider, why would you need such a data structure.
You can get the effect by using an object array:
final static Object tryit[][] = {
{'a',4},
{'b',7},
{'c',8},
};
#Test
public void accessArray( ) {
for (int i = 0; i < tryit.length ; i++) {
char letter = (Character)tryit[i][0];
int value = (Integer)tryit[i][1];
System.out.println(letter + " has value " + value);
}
}
The "#Test" is JUnit annnotation.
Note this approach would be subject to NullPointer and ClassCast exceptions at runtime if the wrong data is entered in the array.

Writing `double...` instead of `[] double`

public MonomialPolynomial(double... coeffs){
List<IMonom> monoms = new ArrayList<IMonom>();
for (int i = 0; i < coeffs.length; i++) {
// zero coeffs might yaffect the degree
if(coeffs[i] != 0)
monoms.add(new Monom(coeffs[i], i));
}
super.monoms = monoms;
}
Why do people write double... and not [] double when they mean to array?
Is there a special meaning for this?
double... declares it a "var args" parameter -- inside your method it's identical to double[] but for the caller, it's much easier to call with varying numbers of arguments (hence var args) without the need to explicitly create an array:
Without var args:
MonomialPolynomial(double[] coeffs) { ...}
...
// explicit array creation necessary
new MonomialPolynomial(new double[] {1, 2, 3)};
With var args:
MonomialPolynomial(double... coeffs) { ...}
...
// array gets created implicitly, so less boilerplate code
new MonomialPolynomial(1, 2, 3);
Edit: One thing to watch out for with var args, only the last argument of a method can be a var args argument. This guarantess there's no ambiguity when calling a method, e.g.
foo(int a, int b...) is unambigious, because the first argument will always be assigned to a and anything after that will be go into of b.
foo(int a..., int... b) on the other hand is ambigious, there's no way to tell if foo(1, 2, 3) means a={1} and b={2, 3} or a={1, 2} and b={3}.
double... is a varargs (variable arguments) feature. This means you can provide the constructor with an array of doubles, or you can provide the constructor with any number of doubles, and it is put into an array for you. (Example: MonomialPolynomial(1.0, 5.0, 6.0).)
It is the vararg feature, that is, all the arguments the function gets are collected into an array. In that case, an array of doubles. The feature is for hardcoded arrays and such. If MonomialPolynomial were to accept a double[], you would have to use such oneliners:
MonomialPolynomial(new double[] {1, 2, 3});
But with variable arguments you may write a bit neater code:
MonomialPolynomial(1, 2, 3);

Categories