1

Im developing for android and compiling with gradle from git using jitpack.io

Im trying to use this library from git for functional programming:

fj - functional programmming for Java 7

I ran the code and got errors even though everything is tested.

The problem is in the class GroupBy:

Source code:

public Collection<Group<S,T>> execute(Collection<T> collection){
    Hashtable<S, Group<S, T>> groups = new Hashtable<S, Group<S, T>>();

    for (T item: collection){
        S classification = grouper.select(item);

        if (!groups.contains(classification)){
            groups.put(classification, new Group<S, T>(classification));
        }
        groups.get(classification).add(item);
    }

    return groups.values();
}

De-Compiled code:

public Collection<GroupBy.Group<S, T>> execute(Collection<T> collection) {
    Hashtable groups = new Hashtable();

    Object item;
    Object classification;
    for(Iterator var3 = collection.iterator(); var3.hasNext(); ((GroupBy.Group)groups.get(classification)).add(item)) {
        item = var3.next();
        classification = this.grouper.select(item);
        if(!groups.contains(classification)) {
            groups.put(classification, new GroupBy.Group(classification));
        }
    }

    return groups.values();
}

I would appreciate any help.

Currently i dont see any reason why the code look different

Thanks

Gur
  • 111
  • 8
  • 1
    decomplilers wont actually decompile to exact source. since its only sees the byte code it will try to decompile to something as close as it can get to source but you will never actually get the exact code you had before even though it should do the same thing – Tomer Shemesh Jun 07 '16 at 17:00
  • OK. I got an answer... 1. The de-compiled code does exactly the same. It's only a transformation of code and optimization by the compiler 2. The error i had was because i used 'contains' instead of 'containKey' – Gur Jun 07 '16 at 17:20

1 Answers1

1

The short answer is that when java is complied information is lost. However the decompiled code functions exactly the same as the code you wrote.

Let's look at it line by line...

public Collection<GroupBy.Group<S, T>> execute(Collection<T> collection) {

This is the same, though it's given the Group class its full name.

    Hashtable groups = new Hashtable();
    Object item;
    Object classification;

As you can see here the variable names and all the generic information is lost. Generics in java can be thought of as a hint to the compiler to check for errors. Once the compiler has finished compiling the information is thrown away (generally).

    for(
        Iterator var3 = collection.iterator(); 
        var3.hasNext();                         
        ((GroupBy.Group)groups.get(classification)).add(item)
    ) {

The enhanced for loop has been replaced by a classic for loop. This is because in bytecode they are the same thing (though a smarter decompiler might have figured this out and written an enhanced for loop here).

The other interesting thing here is that the compiler has put the groups.get(...).add(...) statement inside your for loop. If you think about the contract of for(initialisation; termination; increment) then increment happens upon every loop iteration. So even though you wrote your statement inside the loop, it is the same effect. [There's probably a good reason for doing it this way, I'm not a compiler guru though so I can't say for certain].

        item = var3.next();
        classification = this.grouper.select(item);
        if(!groups.contains(classification)) {
            groups.put(classification, new GroupBy.Group(classification));
        }
    }

    return groups.values();
}

The rest of the code is pretty much exactly what you wrote.

Matthew
  • 10,361
  • 5
  • 42
  • 54