How do I find the length of a multi-dimensional array with reflection on java?
There is no such thing as "length" for multi-dimensional array; it may not be rectangular. I'm guessing you're talking about the number of dimensions. You need to descend into it iteratively and count.
public int getDimensionCount(Object array) {
int count = 0;
Class arrayClass = array.getClass();
while ( arrayClass.isArray() ) {
count++;
arrayClass = arrayClass.getComponentType();
}
return count;
}
Java arrays have lengths per instance, not all arrays in the same dimension have to have equals lengths. That said, you can get the lengths of instances in the.
Dimensions can be counted by the number of '[' in their name, this is quicker than descending the type hierarchy. The following code:
int[][][] ary = {{{0},{1}}};
Class cls = ary.getClass();
boolean isAry = cls.isArray();
String clsName = cls.getName();
System.out.println("is array=" + isAry);
System.out.println("name=" + clsName);
int nrDims = 1 + clsName.lastIndexOf('[');
System.out.println("nrDims=" + nrDims);
Object orly = ary;
for (int n = 0; n < nrDims; n++) {
int len = Array.getLength(orly);
System.out.println("dim[" + n + "]=" + len);
if (0 < len) {
orly = Array.get(orly, 0);
}
}
gives the following output:
is array=true
name=[[[I
nrDims=3
dim[0]=1
dim[1]=2
dim[2]=1
Class clazz = Class.forName("ReflectionTest");
Method m = clazz.getDeclaredMethod("getArray");
Object o1 = m.invoke(o, arg);
int array[][] = (int[][])o1;
System.out.println("Array length: " + array.length);
System.out.println("Array length: " + array[0].length);
Use java.lang.reflect.Array.getLength(obj).
If you like me were trying to get the number of dimensions and the size of them then:
private static int[] getDimentionsOf(final Object expectedArray) {
if (!expectedArray.getClass().isArray()) {
return new int[0];
}
final int dimensionSize = Array.getLength(expectedArray);
final int[] innerDimensions =
(expectedArray.getClass().getComponentType().isArray())
? getDimentionsOf(Array.get(expectedArray, 0))
: new int[0];
final int lenghtPlusOne = innerDimensions.length + 1;
final int[] newDimensions = new int[lenghtPlusOne];
System.arraycopy(innerDimensions, 0, newDimensions, 1, innerDimensions.length);
newDimensions[0] = dimensionSize;
return newDimensions;
}
Related
I would like to re-format a String array based on condition. Say, the array
A = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
int index = 1
Which means I will adjoin the items till index 1 with space and format the array. So, finally, it will be,
A = ["samsung chargers", "fast", "charging", "rapid", "high"]
For the index = 2, the output should be,
A = ["samsung chargers fast", "charging", "rapid", "high"]
I write the code that works, I try to find more concise (but not low performance) way.
StringBuilder builder = null;
..........
int fCount = ...
// format the array to match the string
// values = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
builder = new StringBuilder();
String formated = "";
for (int i = 0; i <= fCount; i++) {
builder.append(values[i]).append(" ");
}
formated = builder.toString().trim();
String[] fVaues = new String[values.length - fCount];
fVaues[0] = formated;
for (int i = 1; i < fVaues.length; i++) {
fVaues[i] = values[i+1];
}
What is the simple way to accomplish it?
This method does the same thing:
static String[] joinUntil(String[] original, int until) {
return Stream.concat(
Stream.of(String.join(" ", Arrays.copyOf(original, until))),
Arrays.stream(Arrays.copyOfRange(original, until, original.length))
).toArray(String[]::new);
}
private static List<String> reFormat(List<String> lst, int index){
String joined = String.join(" ", lst.subList(0, index + 1));
List<String> res = new ArrayList<String>();
res.add(joined);
res.addAll(lst.subList(index + 1, lst.size()));
return res;
}
You could just loop over it, adding the Strings to a second array:
String[] b = new String[a.length - index];
String tmp = a[0];
for(int i = 1; i < a.length; i++) {
if(i <= index) {
tmp += " " + a[i];
if(i == index) {
b[i - index] = tmp;
}
}
else {
b[i - index] = a[i];
}
}
Alright so I've created an array of type int with size 10.
I've initialized it to random values between 1-100.
Now my task is to write a method named output which will take an int array as a parameter and displays all elements of the array in a column like this:
Output
arr[0] : 17
arr[1] : 42
etc etc, but when I do it in eclipse it says
i cannot be resolved to a variable,
so I was thinking of re-initializing it in my method, but wouldn't that give me a whole set of different numbers?
private int [] nums;
public UsingArrays(){
nums = new int [10];
for (int i = 0; i <nums.length; i++){
nums[i] = (int)(Math.random()*100)+1;
}
}
public String Output(){
String string;
string = "Arr[" + i + "]:" + nums[i];
return string;
}
}
i cannot be resolved to a variable
You forgot to surround the whole thing with a for loop that will be declaring & using that i variable :
public void Output(int[] array){
String string = "";
for(int i = 0; i < array.length; i++) {
string += "Arr[" + i + "]:" + array[i] + "\n"; // not recommended
}
System.out.println(string);
}
And in such cases, it would be better if you use a StringBuilder, so as to avoid creating new String instances at each iteration:
public void Output(int[] array){
StringBuilder sb = new StringBuilder();
for(int i = 0; i < array.length; i++) {
sb.append("Arr[" + i + "]:" + array[i] + "\n"); // Accumulate results
}
System.out.println(sb.toString()); // print final result
}
I do not know why you are trying to initialize int[] in a constructor and keep this array as a global variable when you said that 'method named output which will take an int array as a parameter'.
Here is a proper solution according to your requirements:
public static void main(String[] args) {
final int sizeOfArray = 10;
final int[] nums = new int[sizeOfArray];
//JAVA 7
for(int i = 0; i < sizeOfArray; i++){
nums[i] = (int)(Math.random() * 100) + 1;
}
//JAVA 8
IntStream.range(0,sizeOfArray)
.forEach(i -> nums[i] = (int)(Math.random() * 100) + 1);
output(nums);
}
private static void output(final int[] arrayToDisplay){
//JAVA 7
for(int i = 0; i < arrayToDisplay.length; i++){
System.out.printf("arr[%d] : %d \n",i,arrayToDisplay[i]);
}
//JAVA 8
IntStream.range(0,arrayToDisplay.length)
.forEach(i -> System.out.printf("arr[%d] : %d \n",i,arrayToDisplay[i]));
}
You should always make sure that all variables initialized and have an appropriate type assigned to them (at least in Java). If I were you, I would stick to Java 7 version of the code above
This problem won't be complied because there is not definition of what 'i' means in output method.
Another solution can be :
public String Output(){
StringBuffer sb = new StringBuffer();
int i=0;
while(i<nums.length){
sb.append("Arr[" + i + "]:" + nums[i]);
System.out.println(sb.toString());
sb.clear();
}
}
I have a Array of strings and I want to get the number of characters in the particular element in the array of strings,how i can do that?
like a array arr have = {"abc", "bgfgh", "gtddsffg"}
if i use
a.length; I will get the 3 which is the no.of elements in array
but I want a method which when I apply on each element like
for(int = 0; ; i++)
{
int t = a[i].length; //this method doesn't work
}
to return the number of characters in each element
which is the given example has to be 3,5 and 8
PLEASE REPLY?
package stackoverflow.q_24933319;
public class FindLength {
public static void main(String[] args) {
String[] arr = {"abc","bgfgh","gtddsffg"};
System.out.println("Array size is: " + arr.length);
for(String s : arr) {
System.out.println("Value is " + s + ", length is " + s.length());
}
}
}
//Output:
//Array size is: 3
//Value is abc, length is 3
//Value is bgfgh, length is 5
//Value is gtddsffg, length is 8
Unlike arrays, String doesn't have an attribute length, but it has a method length() which returns the String's length (in Unicode code units, see JavaDoc).
Try this: a[i].length().
I think a good idea is to put numbers of characters into another table. If you want, you can after that make some other operation on each of this number outside the for loop.
String [] input = {"aaaa", "sdasdwdas", "sd"};
int [] output = new int [input.length];
for (int i = 0; i < input.length; i++)
output[i] = input[i].length();
I think this code has the answer to your question in at least one of the functions.
public int[] getEachLengthIndividually(String[] arr)
{
int[] retArray = new int[arr.length];
for(int i = 0; i < arr.length; i++)
{
String string = arr[i];
retArray[i] = string.length();
}
return retArray;
}
public int totalSize(String[] arr)
{
int totalSize = 0;
for(String string : arr)
{
totalSize += string.length();
}
return totalSize;
}
public static void main(String[] args)
{
String[] arr = {"abc", "bgfgh", "gtddsffg"};
int[] eachLengthIndividually = getEachLengthIndividually(arr);
int totalLength = getTotalLength(arr);
for(int i = 0; i < eachLengthIndividually.length; i++)
{
System.out.println("The string " + arr[i] + " at index " + i + " has length of " + eachLengthIndividually[i]);
}
System.out.println("The total length of all strings in the array is " + totalLength);
}
I already have the following code
public class Qn3
{
static BigDecimal[] accbal= new BigDecimal[20];
private static Integer[] accnums = new Integer[5];
public static void main(String[] args)
{
int count;
accnums = {1,2} //i cant add this line of code as well, what is wrong?
while(accnums.length < 5)
{
count = accnums.number_of_filled_up_indexes
//this is not actual code i know
//do this as the number of values in the array are less than 5
break;
}
//do this as number of values in the array are more than 5
}
}
I must use this code there is no changing this is a requirment, so please dont suggest to use arraylist and such (i am aware of other array types and methods)
The problem is that as I have already declared that accnums must contain only 5 values, that is predefined.
I am trying to perform a check whether the ones that are not null and if all are null. To do this I have tried this but this is giving me 5 p(pre-defined integer array value not what I want).
public static void main(String[] args)
{
int count = 0;
accnums = new Integer[] {1,2,null,null,null};
for (int index = 0; index < accnums.length; index++)
{
if(accnums[index] != null)
{
count++;
}
}
System.out.println("You have used " + count + " slots);
}
Try this...
accnums[0] = new Integer(1);
accnums[1] = new Integer(2);
Both the below will work if done during Declaration and Initializing time of and array.
Integer[] arr = new Integer[]{1,2,3};
Integer[] arr = {1,2,3}
But when you just declare the array as
Integer[] arr = new Integer[3]; // Still array holds no Object Reference Variable
then later initialize it this way...
arr = new Integer{1,2,3,}; // At this time it hold the ORV
Array are always initialized whether used at class or method scope, so for an int array all the values will be set to default as 0, and for Integer it will be null, as its an Wrapper object.
Eg:
Integer[] arr = new Integer[5];
arr[0] = 1;
arr[1] = 2;
System.out.println(arr.length);
for (Integer i : arr){
if (i!=null){
count++;
}
}
System.out.println("Total Index with Non Null Count :"+count);
}
accnums[0] = 1;
accnums[1] = 2;
final int count = accnums.length
- Collections.frequency(Arrays.asList(accnums), null);
System.out.println("You have used " + count + " slots");
or, if you really must do it manually...
int count;
for (final Integer val : accnums) {
if (val != null) {
++count;
}
}
The following code will print 2
String word = "bannanas";
String guess = "n";
int index;
System.out.println(
index = word.indexOf(guess)
);
I would like to know how to get all the indexes of "n" ("guess") in the string "bannanas"
The expected result would be: [2,3,5]
This should print the list of positions without the -1 at the end that Peter Lawrey's solution has had.
int index = word.indexOf(guess);
while (index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index + 1);
}
It can also be done as a for loop:
for (int index = word.indexOf(guess);
index >= 0;
index = word.indexOf(guess, index + 1))
{
System.out.println(index);
}
[Note: if guess can be longer than a single character, then it is possible, by analyzing the guess string, to loop through word faster than the above loops do. The benchmark for such an approach is the Boyer-Moore algorithm. However, the conditions that would favor using such an approach do not seem to be present.]
Try the following (Which does not print -1 at the end now!)
int index = word.indexOf(guess);
while(index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index+1);
}
This can be done in a functional way with Java 9 using regular expression:
Pattern.compile(Pattern.quote(guess)) // sanitize input and create pattern
.matcher(word) // create matcher
.results() // get the MatchResults, Java 9 method
.map(MatchResult::start) // get the first index
.collect(Collectors.toList()) // collect found indices into a list
);
Here's the Kotlin Solution to add this logic as a new a new methods into CharSequence API using extension method:
// Extension method
fun CharSequence.indicesOf(input: String): List<Int> =
Regex(Pattern.quote(input)) // build regex
.findAll(this) // get the matches
.map { it.range.first } // get the index
.toCollection(mutableListOf()) // collect the result as list
// call the methods as
"Banana".indicesOf("a") // [1, 3, 5]
String string = "bannanas";
ArrayList<Integer> list = new ArrayList<Integer>();
char character = 'n';
for(int i = 0; i < string.length(); i++){
if(string.charAt(i) == character){
list.add(i);
}
}
Result would be used like this :
for(Integer i : list){
System.out.println(i);
}
Or as a array :
list.toArray();
With Java9, one can make use of the iterate(int seed, IntPredicate hasNext,IntUnaryOperator next) as follows:-
List<Integer> indexes = IntStream
.iterate(word.indexOf(c), index -> index >= 0, index -> word.indexOf(c, index + 1))
.boxed()
.collect(Collectors.toList());
System.out.printlnt(indexes);
int index = -1;
while((index = text.indexOf("on", index + 1)) >= 0) {
LOG.d("index=" + index);
}
Java 8+
To find all the indexes of a particular character in a String, one can create an IntStream of all the indexes and filter over it.
import java.util.stream.Collectors;
import java.util.stream.IntStream;
//...
String word = "bannanas";
char search = 'n';
//To get List of indexes:
List<Integer> indexes = IntStream.range(0, word.length())
.filter(i -> word.charAt(i) == search).boxed()
.collect(Collectors.toList());
//To get array of indexes:
int[] indexes = IntStream.range(0, word.length())
.filter(i -> word.charAt(i) == search).toArray();
String word = "bannanas";
String guess = "n";
String temp = word;
while(temp.indexOf(guess) != -1) {
int index = temp.indexOf(guess);
System.out.println(index);
temp = temp.substring(index + 1);
}
String input = "GATATATGCG";
String substring = "G";
String temp = input;
String indexOF ="";
int tempIntex=1;
while(temp.indexOf(substring) != -1)
{
int index = temp.indexOf(substring);
indexOF +=(index+tempIntex)+" ";
tempIntex+=(index+1);
temp = temp.substring(index + 1);
}
Log.e("indexOf ","" + indexOF);
Also, if u want to find all indexes of a String in a String.
int index = word.indexOf(guess);
while (index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index + guess.length());
}
I had this problem as well, until I came up with this method.
public static int[] indexesOf(String s, String flag) {
int flagLen = flag.length();
String current = s;
int[] res = new int[s.length()];
int count = 0;
int base = 0;
while(current.contains(flag)) {
int index = current.indexOf(flag);
res[count] = index + base;
base += index + flagLen;
current = current.substring(current.indexOf(flag) + flagLen, current.length());
++ count;
}
return Arrays.copyOf(res, count);
}
This method can be used to find indexes of any flag of any length in a string, for example:
public class Main {
public static void main(String[] args) {
int[] indexes = indexesOf("Hello, yellow jello", "ll");
// Prints [2, 9, 16]
System.out.println(Arrays.toString(indexes));
}
public static int[] indexesOf(String s, String flag) {
int flagLen = flag.length();
String current = s;
int[] res = new int[s.length()];
int count = 0;
int base = 0;
while(current.contains(flag)) {
int index = current.indexOf(flag);
res[count] = index + base;
base += index + flagLen;
current = current.substring(current.indexOf(flag) + flagLen, current.length());
++ count;
}
return Arrays.copyOf(res, count);
}
}
A class for splitting strings I came up with. A short test is provided at the end.
SplitStringUtils.smartSplitToShorterStrings(String str, int maxLen, int maxParts) will split by spaces without breaking words, if possible, and if not, will split by indexes according to maxLen.
Other methods provided to control how it is split: bruteSplitLimit(String str, int maxLen, int maxParts), spaceSplit(String str, int maxLen, int maxParts).
public class SplitStringUtils {
public static String[] smartSplitToShorterStrings(String str, int maxLen, int maxParts) {
if (str.length() <= maxLen) {
return new String[] {str};
}
if (str.length() > maxLen*maxParts) {
return bruteSplitLimit(str, maxLen, maxParts);
}
String[] res = spaceSplit(str, maxLen, maxParts);
if (res != null) {
return res;
}
return bruteSplitLimit(str, maxLen, maxParts);
}
public static String[] bruteSplitLimit(String str, int maxLen, int maxParts) {
String[] bruteArr = bruteSplit(str, maxLen);
String[] ret = Arrays.stream(bruteArr)
.limit(maxParts)
.collect(Collectors.toList())
.toArray(new String[maxParts]);
return ret;
}
public static String[] bruteSplit(String name, int maxLen) {
List<String> res = new ArrayList<>();
int start =0;
int end = maxLen;
while (end <= name.length()) {
String substr = name.substring(start, end);
res.add(substr);
start = end;
end +=maxLen;
}
String substr = name.substring(start, name.length());
res.add(substr);
return res.toArray(new String[res.size()]);
}
public static String[] spaceSplit(String str, int maxLen, int maxParts) {
List<Integer> spaceIndexes = findSplitPoints(str, ' ');
List<Integer> goodSplitIndexes = new ArrayList<>();
int goodIndex = -1;
int curPartMax = maxLen;
for (int i=0; i< spaceIndexes.size(); i++) {
int idx = spaceIndexes.get(i);
if (idx < curPartMax) {
goodIndex = idx;
} else {
goodSplitIndexes.add(goodIndex+1);
curPartMax = goodIndex+1+maxLen;
}
}
if (goodSplitIndexes.get(goodSplitIndexes.size()-1) != str.length()) {
goodSplitIndexes.add(str.length());
}
if (goodSplitIndexes.size()<=maxParts) {
List<String> res = new ArrayList<>();
int start = 0;
for (int i=0; i<goodSplitIndexes.size(); i++) {
int end = goodSplitIndexes.get(i);
if (end-start > maxLen) {
return null;
}
res.add(str.substring(start, end));
start = end;
}
return res.toArray(new String[res.size()]);
}
return null;
}
private static List<Integer> findSplitPoints(String str, char c) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
list.add(i);
}
}
list.add(str.length());
return list;
}
}
Simple test code:
public static void main(String[] args) {
String [] testStrings = {
"123",
"123 123 123 1123 123 123 123 123 123 123",
"123 54123 5123 513 54w567 3567 e56 73w45 63 567356 735687 4678 4678 u4678 u4678 56rt64w5 6546345",
"1345678934576235784620957029356723578946",
"12764444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444",
"3463356 35673567567 3567 35 3567 35 675 653 673567 777777777777777777777777777777777777777777777777777777777777777777"
};
int max = 35;
int maxparts = 2;
for (String str : testStrings) {
System.out.println("TEST\n |"+str+"|");
printSplitDetails(max, maxparts);
String[] res = smartSplitToShorterStrings(str, max, maxparts);
for (int i=0; i< res.length;i++) {
System.out.println(" "+i+": "+res[i]);
}
System.out.println("===========================================================================================================================================================");
}
}
static void printSplitDetails(int max, int maxparts) {
System.out.print(" X: ");
for (int i=0; i<max*maxparts; i++) {
if (i%max == 0) {
System.out.print("|");
} else {
System.out.print("-");
}
}
System.out.println();
}
This is a java 8 solution.
public int[] solution (String s, String subString){
int initialIndex = s.indexOf(subString);
List<Integer> indexList = new ArrayList<>();
while (initialIndex >=0){
indexList.add(initialIndex);
initialIndex = s.indexOf(subString, initialIndex+1);
}
int [] intA = indexList.stream().mapToInt(i->i).toArray();
return intA;
}
This can be done by iterating myString and shifting fromIndex parameter in indexOf():
int currentIndex = 0;
while (
myString.indexOf(
mySubstring,
currentIndex) >= 0) {
System.out.println(currentIndex);
currentIndex++;
}
Try this
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));