Getting key-value from Object in Java This takes a collection of Objects from JavaScript and puts them into a Java project. How can I improve this code? What's the best solution?

// JavaScript fetch data into List ChartData

int i = 0;
int k = 0;

// output
for (Object currObj : ChartData) {

    // get all fields of Object
    for (Field field : currObj.getClass().getDeclaredFields()) {

        field.setAccessible(true); 
        Object value = field.get(currObj); 
         // parse only HashMap
        if ((value != null)&amp;&amp;value.getClass().toString().equalsIgnoreCase("class        java.util.HashMap"))) {

            //get HashMap
            HashMap hm = (HashMap)value;
            // Get a set of the entries
            Set set = hm.entrySet();
            // Get an iterator
            Iterator j = set.iterator();

            // Display elements
            while(j.hasNext()) {
               Map.Entry me = (Map.Entry)j.next();
               if ((me.getKey().toString().equalsIgnoreCase("y"))){
                 assertTrue(Long.parseLong(me.getValue().toString()) == anArrayOfObjects[i][0]); // check pairs                                
                 System.out.println("Actual y value - " + me.getValue().toString() + " expected value - " + anArrayOfObjects[k][0].toString());
                 i++;  
               }

               if ((me.getKey().toString().equalsIgnoreCase("x"))){
                  assertTrue(Long.parseLong(me.getValue().toString()) == anArrayOfObjects[k][1]);// check pairs 
                  System.out.println("Actual x value - " + me.getValue().toString() + " expected value - " + anArrayOfObjects[k][1].toString());
                  k++;
               }
            }
        }
    }
}
Naming Convention

It is common practice and part of the SUN / Oracle Code Conventions for the Java Programming Language to start variable names with lowercase.
Thus, you might want to rename ChartData to chartData.

Oh, and j is not an acceptable name for an Iterator.
A few lines down, I can no longer remember what j was.
Usually, j is an int and used because i was used already.
And in fact you already do have an int i.

In such a case, name the Iterator it or iter or even iterator but not j.

Also, the name me for Map.Entry is a bit confusing, because the abbreviation me is a valid English word at the same time.
I'd rename me to entry.

Iterating over Map entries

Your code for iterating over the map entries is too complex.

Here's the relevant part of your code:

HashMap hm = (HashMap) value; // context
Set set = hm.entrySet();
Iterator j = set.iterator();
while (j.hasNext()) {
    Map.Entry me = (Map.Entry) j.next();
    // Do something with me.
}


You can remove the cast by telling the Set and the Iterator that they are from a Map, which means they are a Set&lt;Map.Entry&gt; and an Iterator&lt;Map.Entry&gt;.
This simplifies the code as follows:

HashMap hm = (HashMap) value; // context
Set&lt;Map.Entry&gt; set = hm.entrySet();
Iterator&lt;Map.Entry&gt; j = set.iterator();
while (j.hasNext()) {
    Map.Entry me = j.next();
    // Do something with me.
}


You can further simplify this by turning this into a for-each loop:

HashMap hm = (HashMap) value; // context
for (Map.Entry me : hm.entrySet()) {
    // Do something with me.
}


Abstract datatypes

Whether your map is a HashMap or something else is probably irrelevant.
Therefore you might want to change the datatype of variable hm from HashMap to Map.

Map hm = (Map) value;


How to check types

Java has an instanceof operator.

Your type check compares the toString() result of the class.
That has a few issues.


Your comparison relies on a specific format of Class.toString() which is not guaranteed. If you must compare the name, use getName() instead of toString().
Your comparison is case-insensitive, which is definitely the wrong thing to do in a case-sensitive language. java.util.HashMap and java.util.hashmap could in theory both exist but would be separate classes. Your code would treat java.util.hashmap as if it were the same as java.util.HashMap, which is wrong.
Your comparison checks on the class, ruling out possible subclasses of HashMap as well as alternative Map implementations. In a broader sense, you're violating the LSP - Liskov Substitution Principle.


You might want to go for this code to check the type:

Object value = field.get(currObj);
if (value instanceof HashMap) // ...


or even

Object value = field.get(currObj);
if (value instanceof Map) // ...


Interlude: New source code as of now

for (Object currObj : chartData) {
    for (Field field : currObj.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        Object value = field.get(currObj);
        if (value instanceof Map) {
            Map hm = (Map) value;
            for (Map.Entry entry : hm.entrySet()) {
                if ((entry.getKey().toString().equalsIgnoreCase("y"))) {
                    assertTrue(Long.parseLong(me.getValue().toString()) == anArrayOfObjects[i][0]); // check pairs
                    System.out.println("Actual y value - " + me.getValue().toString() + " expected value - " + anArrayOfObjects[k][0].toString());
                    i++;
                }

                if ((entry.getKey().toString().equalsIgnoreCase("x"))) {
                    assertTrue(Long.parseLong(me.getValue().toString()) == anArrayOfObjects[k][1]);// check pairs
                    System.out.println("Actual x value - " + me.getValue().toString() + " expected value - " + anArrayOfObjects[k][1].toString());
                    k++;
                }
            }
        }
    }
}


Method length

This method is far too long to be even close to maintainable source code.
As software craftsmen, we say that regarding method length Java code is maintainable if (almost) all of its methods have 5 or fewer lines.
10 lines is something which I already do not accept in production code.
(Exceptions like some GUI creation code apply.)

The code should be split into several methods.
I know that you might even have tried this - and failed, due to the local variables i and k.

Let's remember what Uncle Bob said: "Long functions are where classes use to hide." and "Extract 'till you drop" (Robert C. Martin, "Clean Code")

Refactorings to apply to get smaller methods


Extract method object.
Turn local variables i and k into fields and introduce getters for them (you wouldn't increment them if you wouldn't need them later).
Refactor the constructor argument into an argument to invoke().
Rename invoke to visit.
Extract every multiline block into a separate method with a meaningful name.
Make the two branches for "x" and "y" look identical by replacing everything which is different with variables. For that piece of code which is different we use two methods implementing a functional interface Incrementor so we can store a method reference in a variable.


Here's how this looks like as a class:

private static class ChartDataVisitor {
    private int i = 0;
    private int k = 0;

    public void visit(Iterable&lt;Object&gt; chartData) throws IllegalAccessException {
        reset();
        visitChartData(chartData);
    }

    private void reset() {
        i = 0;
        k = 0;
    }

    private void visitChartData(Iterable&lt;Object&gt; chartData) throws IllegalAccessException {
        for (Object currObj : chartData) visitObject(currObj);
    }

    private void visitObject(Object currObj) throws IllegalAccessException {
        for (Field field : currObj.getClass().getDeclaredFields()) visitField(currObj, field);
    }

    private void visitField(Object currObj, Field field) throws IllegalAccessException {
        field.setAccessible(true);
        Object value = field.get(currObj);
        if (value instanceof Map) visitMap((Map) value);
    }

    private void visitMap(Map&lt;?, ?&gt; hm) {
        hm.entrySet().forEach(this::visitEntry);
    }

    private void visitEntry(Map.Entry&lt;?, ?&gt; entry) {
        visitEntryDetails(entry, "y", i, 0, this::incrementI);
        visitEntryDetails(entry, "x", k, 1, this::incrementK);
    }

    private void visitEntryDetails(Map.Entry&lt;?, ?&gt; entry, String string, int index1, int index2, Incrementor incrementor) {
        if ((entry.getKey().toString().equalsIgnoreCase(string)))
            visitMatchingDetails(entry, string, index1, index2, incrementor);
    }

    private void visitMatchingDetails(Map.Entry&lt;?, ?&gt; entry, String string, int index1, int index2, Incrementor incrementor) {
        final String valueAsString = entry.getValue().toString();
        final Long v = anArrayOfObjects[index1][index2];
        assertTrue(Long.parseLong(valueAsString) == v); // check pairs
        System.out.println("Actual " + string + " value - " + valueAsString + " expected value - " + v.toString());
        incrementor.increment();
    }

    @FunctionalInterface
    private static interface Incrementor {
        void increment();
    }

    private void incrementK() {
        k++;
    }

    private void incrementI() {
        i++;
    }
}


You might notice that not a single method contains {} inside.
That's the whole point.
{} are an opportunity to extract.
Good methods do one thing, they do it well and they do it only.
By having {} inside, you loudly declare that your method is doing more than one thing (or in case of try that the language Java is inconsistent because otherwise it would allow for a try or catch or finally without braces).

You're of course free to reformat it to bring back the removed {}, if you like or if there are militant "{}-Pros" around you (I was one of them myself once, not so long ago).
Today I tend to avoid {} to show off "Look Ma, no {}!" - I don't need them anymore.

Unit Testing

The methods in the new class do not need to be private.
They could as well be package default or public, depending on your business logic.
Because they need not be private, you can easily unit test them individually - you can now test your business logic from inside to the out.
The various layers that were already there (nested block structure in your code) have become accessible individually.
Think of an Onion or Matryoshka.

Warning

My names visit* and similar are not very meaningful. They are physical names. I couldn't come up with better names because I have no idea about what your code is doing. I don't know what the map contains.

You should change some or even all of the the visit* method names to something which communicates the intent of your business logic much better.