C# Multidimensional Arrays vs Java Multidimensional Array - java

I'm relatively new to C# and the way it handles multidimensional arrays compared to Java is screwing with me.
I'm sure there's a simple solution and that I'm gonna feel really stupid for not realizing it, but I can't seem to find an answer online or figure it out myself.
Consider the following code snippet in java:
Object firstElement(Object[] arr) {
return arr[0];
}
This would return the first element of an array of any number of dimensions; however, in C# this will throw out an error for greater than one dimension because it doesn't recognize a multidimensional array as an object array. The only way to do this I found was by casting the multidimensional array to a System.Array and then using the following code:
object firstElement(Array arr) {
foreach (object obj in arr)
return obj;
}
Is it even possible to do this without a foreach loop in the function? I have tried returning the object using arr.GetValue(0) but this will throw an error again if the array is not one dimensional. Thanks for helping this C# newbie out!

C# expects you to address every dimension in a multidimensional array even if you are meaning to access, say, [0,0].
Object firstElement(Object[] arr) {
return arr[0];
}
For this reason, the code above will throw at compile time.
this code only takes one-dimensional arrays. Try this instead:
Object firstElement(Object[][] arr) {
return arr[0][0];
}
Adjust amount of brackets according to the amount of dimensions.
It is also more common to use the keyword-aliases for primitives like object or int. I do suspect you will replace the Object with an actual class / struct instance or primitive at some point.
object firstElement(object[][] arr) {
return arr[0][0];
}
What I would suggest you reading up on are the two different types of "multidimensional"-arrays: Jagged and actual multidimensional-arrays. The key difference is that each row has to have the same amount of columns in a multidimensional-array whereas the jagged array can be irregular in this regard.
/edit:
I seem have to misunderstood your intention. I believe you try to get every first element of each row. If that is the case then try this one:
List<object> firstElements(object[][] arr)
{
List<object> firsts = new List<object>();
for(int i = 0; i < arr.length; i++)
{
firsts.Add(arr[i][0]);
}
return firsts;
}

Related

Process multi dimensional arrays in Java

What is the best way to take in a multi dimensional array as a method parameter in the form of an object and then reconstruct it as a variable inside that method? The reason I want to pass the array in as an object is because I want my code to be able to use any n dimensional array. I could circumvent this by using method overloading but making hundreds of identical methods just to account for all possible array dimensions seems like a very bad way to do it. However, using an object as a parameter causes a new set of challenges since I have no way to initialize that array since you normally need to explicitly declare an arrays dimensions. Based on some of my research I have figured out a way to determine the dimensions of an array passed in as an object which you can view in the following code snippet.
public static void callTestArray() {
var matrix = new int[][]{{1,2}, {4, 6, 7}};
test(matrix);
}
public static void test(Object obj) {
final int dimensions = dimensionOf(obj);
System.out.println("Dimensions:" + dimensions);
//I can't create a variable from this though since I need to hard code the dimensions of the array
}
/**
* This returns the amount of dimensions an array has.
*/
public static int dimensionOf(Object arr) {
int dimensionCount = 0;
Class<?> c = arr.getClass(); // getting the runtime class of an object
while (c.isArray()) { // check whether the object is an array
c = c.getComponentType(); // returns the class denoting the component type of the array
dimensionCount++;
}
return dimensionCount;
}
I have been looking around for a while now but I cant find an object that allows me to pass in any n dimensional array in that allows me to easily access all of an arrays typical information? Was this not included in Java or am I just missing it? That being said since 255 is the max amount of dimensions an array can have I could make my own utils class to handle this but it would require a ton of redundancies and effort to handle all cases. I just want to make sure it has not already been made before I waste hours making something like that. Also if anyone has a better way of doing it with any internal java libraries please let me know!
Instead of passing around arrays we more often than not use collections like ArrayList, this allows us some abstraction and allows us to add some common methods to it. Note that ArrayList doesn't extend arrays, it simply implements a list interface.
I recommend the same thing for you, instead of passing around an array, consider encapsulating the array in a class and pass that class around. Use the class to do certain simplifications, for instance you might have a method allowing it to apply a function to each element of the matrix or one to resize the matrix.
You might track your matrix's dimensions in different variables allowing you to resize it without re-allocating the array (like an ArrayList does)
Another advantage of the encapsulation, if you wish to do something different like make a sparse matrix out of it, you could re-implement the underlying code without changing the ways it's used (Like the way ArrayList and LinkedList have the same interface but do things different ways for different use cases)
Your other conditions seem to work for this Matrix object as well as it would arrays, for instance you would pass dimensions into the constructor to create it initially (Although, as I said, you could easily expand it later, especially if you used an ArrayList of ArrayLists for your underlying implementation, if you needed that)
I think the reason it's not included in Java is that it is not very commonly used and quite easy to implement, but if you really don't want to do it yourself, apache has a Matrix implementaiton that looks like it will fit.
We use time series data like hourly tempatures a lot (Often down to 10 second resolution for a day) and so we built our own class that essentially represents a line on a graph with the y axis of "Date", like a linked list but each value is timestamped. This structure is AMAZINGLY useful for us and I often wonder why it's not in Java, but I think I just answered my own question, not used enough.
This is a job for varargs:
public static void main(String[] args) {
var matrix = new int[][]{{1,2}, {4, 6, 7}};
System.out.println("Length is: " + getSize(matrix));
}
public static int getSize(int[]... multiArray) {
return multiArray.length;
}
which prints out:
Length is: 2
Also, unless you have to use an array to hold your int arrays, I would use an ArrayList<int[]> instead. That way you can easily add to your list like:
ArrayList<int[]> multiArray = new ArrayList<>();
multiArray.add(new int[]{1,2,3});
multiArray.add(new int[]{4,5,6});
and then you can get its size by simply calling:
multiArray.size()
Here's my attempt. You use Object as the parameter and then check for the array dimension in the body of the method. In this example, I only limit it to 3D array but you can go up to any dimension.
public class Main{
static void process(Object o){
if (o instanceof int[]){
int[] a = (int[]) o;
System.out.println("1D. length is " + a.length);
} else if (o instanceof int[][]){
int[][] a = (int[][]) o;
System.out.println("2D. row=" + a.length + ", col=" + a[0].length);
} else if (o instanceof int[][][]){
int[][][] a = (int[][][]) o;
System.out.println("3D. row=" + a.length + ", col=" + a[0].length + ", depth=" + a[0][0].length);
} else {
System.out.println("Unsupported array dimension.");
}
}
public static void main(String[] args) {
int[] a = {1,2,3};
int[][] b = {{1,2,3},{1,2,3}};
int[][][] c = {
{ {1,2,3}, {1,2,3} },
{ {1,2,3}, {1,2,3} }
};
process(a);
process(b);
process(c);
}
}
Output:
1D. length is 3
2D. row=2, col=3
3D. row=2, col=2, depth=3

How to cast a multidimensional array without knowing the dimension in Java

There is a multidimensional String array being passed in as an Object.
I'm supposed to "unfold" it and process each of its primitive entries.
There's no way to know the dimensions other than by looking at the Object itself.
The difficulty i'm having is in casting. I can look up the array dimension by invoking its getClass().getName() and counting the [-s there.
But then how to cast it?
String[] sa = (String[]) arr;
is giving
Exception in thread "main" java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [Ljava.lang.String;
Can this casting be done without any use of reflection?
Note - The array can be of any dimension - not just 1 or 2.
TIA.
If you want to work with an array which dimension is not known at the compile time, I would suggest you to recursively process all of its entries instead of trying to cast it.
You can use object.getClass().isArray() method to check if the current entry is an array and then iterate over it using Array.getLength(object) and Array.get(object, i):
public static void main(String[] args) {
Object array = new String[][] {new String[] {"a", "b"}, new String[] {"c", "d"}};
processArray(array, System.out::println);
}
public static void processArray(Object object, Consumer<Object> processor) {
if (object != null && object.getClass().isArray()) {
int length = Array.getLength(object);
for (int i = 0; i < length; i ++) {
Object arrayElement = Array.get(object, i);
processArray(arrayElement, processor);
}
} else {
processor.accept(object);
}
}
If the size of the array is not known statically (at compile time), then it's logically impossible to get the length relying solely on static means, i.e. without use of dynamic means.
Perhaps this question has the solution you need:
Getting the field "length" in a Java array using reflection

Array as attribute in an object [duplicate]

This question already has answers here:
How do I do a deep copy of a 2d array in Java?
(7 answers)
Closed 4 years ago.
I'm relatively new to Java, and I just learned this
import java.util.Arrays;
public class Foo {
private int[][] foo;
public Foo(int[][] arr) {
this.foo = arr;
}
#Override
public String toString() {
return Arrays.deepToString(this.foo).replace("],", "],\n");
}
public static void main(String[] args) {
int[][] p = { { 0, 0 }, { 0, 0 } };
Foo g = new Foo(p.clone()); // doesn't work with p nor p.clone()
System.out.println(g);
p[0][0] = 1;
System.out.println(g);
}
}
Here I create an object with a reference to another object, and I can alter the object from the outside since I have the reference to the thing I just passed as an argument to the constructor.
This, although I understand why it happens, seems counterintuitive to me. If I save something as an attribute of an object I expect the object to have a “private” copy not accessible outside.
And I tried with .clone() and doesn't solve it. So the question is...
How is this usually done? Do I need to write a few for loops inside the constructor to get every value out of the argument?
 (Or is this a non-issue?)
This last part of the question is important, may be this is a non-issue. Or do people do “something” (a few loops to get a deep clone)?
The problem here is that java doesn't really have 2-D arrays. This:
int[][] x;
is an array of int arrays. It is not a 2D int array, though of course an array of int arrays does feel a lot like a 2D array. For most intents and purposes it iS a 2D int array, unless it isn't, and with clone, it isn't. The clone() impl of an array makes a new array and just copies each and every value, verbatim, into the new array. Which means that your array of int arrays is cloned, but the inner int arrays are not.
When treating int[][] as 'this is a 2D array', yeah, that is unintuitive. When treating int[][] as 'an array of int arrays', it is quite intuitive. You wouldn't expect an array of arraylists, when cloned, to also clone each individual arraylist either.
Soo.. how do you deep-clone an array of arrays (of arrays of arrays)? See How do I do a deep copy of a 2d array in Java? for lots of options :)

Cannot invoke indexOf on an Array of strings?

I'm writing a method to calculate the distance between 2 towns in a given array by adding all the entries between the indexes of the two towns in the second array, but I can't invoke indexOf on the first array to determine where the addition should start. Eclipse is giving me the error "Cannot invoke indexOf on array type String[]" which seems pretty straight forward, but I do not understand why that won't work.
Please note the program is definitely not complete.
public class Exercise_3 {
public static void main(String[] args){
//Sets the array
String [] towns={"Halifax","Enfield","Elmsdale","Truro","Springfield","Sackville","Moncton"};
int[] distances={25,5,75,40,145,55,0};
distance(towns, distances, "Enfield","Truro");
}
public static int distance(String[] towns,int[] distances, String word1, String word2){
int distance=0;
//Loop checks to see if the towns are in the array
for(int i=0; i<towns.length; i++){
if(word1!=towns[i] || word2!=towns[i] ){
distance=-1;
}
//Loop is executed if the towns are in the array, this loop should return the distance
else{
for(int j=0; j<towns.length; j++){
*int distance1=towns.indexOf(word1);*
}
}
}
return distance;
}
}
No, arrays do not have any methods you can invoke. If you want to find the index of an given element, you can replace String[] by ArrayList<String>, which has an indexOf method to find elements.
It doesn't work because Java is not JavaScript.
The latter offers an array prototype that actually exposes the function indexOf, while the former does not.
Arrays in JavaScript are completely different from their counterparts in Java.
Anyway, you can be interested in the ArrayList class in Java (see here for further details) that is more similar to what you are looking for.
How about this (from this post)?
There are a couple of ways to accomplish this using the Arrays utility class.
If the array is not sorted:
java.util.Arrays.asList(theArray).indexOf(o)
If the array is sorted, you can make use of a binary search for performance:
java.util.Arrays.binarySearch(theArray, o)
I hope this helps you. If it doesn't, please downvote.

Is there a way to use the compareTo() method for a data set, without iterating through each element of the set?

I am wondering if there is a way to use compareTo() without having to iterate through each string element in the data set, I'm pretty sure this is not possible using arrays, but is there a data structure that is capable of working in that way?
See example below for clearer explanation:
public static int PronounDetector(String [] pronouns)
{
String [] you = {"you", "You"};
for (int i = 0; i < pronouns.length; i++)
{
if (pronouns[i].compareTo(you) == 0)
//Is there a way for compareTo to run through
//the entire String data set without having to make
//it iterate through each element using a for loop?
{
return 2;
}
}
}
EDIT: I understand that no matter what the program will iterate through the data set, (how else will it find a match?), I am just looking to see if there is a way to do it without me actually having the physically type in the for loop.
The must be meet two conditions if you want to skip some data during search processing.
The data must be related.
The data must be organized.
You can improve your search, by sorting the array and then compare from the middle.
Then in each step you will reduce element that must be compare by half.
Instead of array you can used TreeMap, that will store the data in tree structure to have same result.
Code example:
public static boolean contains(String[] array, String key) {
Objects.requireNonNull(array,"The array must not be null");
Objects.requireNonNull(array,"The key must not be null");
String[] copy = array.clone();
Arrays.sort(copy);
return Arrays.binarySearch(copy, key) != -1;
}
Yes, you don't have to "double iterate" (even though that's exactly what happens under the hood) you can convert the array you to a string and search it using contains():
String youStr = Arrays.deepToString(you);
System.out.println(youStr.contains(pronouns[0])); // prints 'true'

Categories

Resources