Archive for category java

Importing and debugging Eclipse projects in IntelliJ IDEA

Last week I faced a situation to import some Eclipse projects to IntelliJ IDEA, my default Java IDE. IntelliJ IDEA supports this integration, just go to File > New > Project from Existing Sources… and select a directory where Eclipse .project or .classpath files are located.

The project was imported successfully, it had some test compilation errors and it was all done for that moment. But, after running the project, I noted that I couldn’t debug some classes as well as I got used at Eclipse.

It was because, by default, IntelliJ IDEA uses the javac compiler and Eclipse has its own Java compiler that is part of JDT core. IntelliJ IDEA doesn’t proceed on code compilation when it finds the first error, even for test code or code that isn’t part of the build. The Eclipse compiler is able to proceed on code compilation even if it has compilation errors, so it is possible to run / debug code that doesn’t compile at all.

The solution, in this case, is to switch IntelliJ IDEA to use the Eclipse compiler. Just go to File > Settings > Build, Execution, Deployment > Compiler > Java compiler and change the drop down box "Use compiler:" to Eclipse and that is done.

I did that and now I am able to run / debug the Eclipse project using IntelliJ IDEA very well.

I have found the solution here:

Enable Partial Compile IntelliJ
What is the difference between javac and the Eclipse compiler?

Have you faced a situation like this? Have you done another solution than mine? Drop your comments here! 🙂

Tags: , , , ,

Converting a Map to a List in Java 8, Groovy and Ruby

Some days ago I was developing a task on a Gradle project and I faced with a situation where I had to convert a Map < String, List < String >> to List < Pair >, each pair containing the key and one element from the List.

I decided to compare the solution in three different languages: Java 8 (using lambdas and the Streams API), Groovy and Ruby to see how concise and expressive they would be. Then, I created the Groovy code and it looked like this:

#!/usr/bin/env groovy

def map = ["a" : ["1", "2", "3"], "b" : ["4", "5", "6"], "c" : ["7"]]

println map.collectMany { key, values -> values.collect {value -> [key, value]}}

Running the above code, the result is below:

[[a, 1], [a, 2], [a, 3], [b, 4], [b, 5], [b, 6], [c, 7]]

The Ruby version looked like this:

#!/usr/bin/env ruby

map = { "a" => ["1", "2", "3"], "b" => ["4", "5", "6"], "c" => ["7"] }

p map.collect {|key, values| values.map {|value| [key, value] } }.flatten(1)

The Ruby program generated the following output:

[["a", "1"], ["a", "2"], ["a", "3"], ["b", "4"], ["b", "5"], ["b", "6"], ["c", "7"]]

Below is the Java 8 version, using lambdas, Streams and the Collectors API:

        Map< String, List < String >> values = new HashMap<>();
        values.put("a", Arrays.asList("1", "2", "3"));
        values.put("b", Arrays.asList("4", "5", "6"));
        values.put("c", Collections.singletonList("7"));

        List< Pair > result = values.
                entrySet().
                stream().
                collect(ArrayList< Pair >::new,
                        (pairs, entry) -> entry.
                                getValue().
                                stream().
                                forEach(value ->
                                        pairs.add(new Pair(entry.getKey(), value))), List< Pair >::addAll);

private static class Pair {

    private final String first;
    private final String second;

    public Pair(String first, String second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public String toString() {
        return new StringBuilder("Pair{")
                .append("first='")
                .append(first).append('\'')
                .append(", second='")
                .append(second)
                .append('\'')
                .append('}')
                .toString();
    }
}

Running the Java 8 version produced the following output:

[Pair{first='a', second='1'}, Pair{first='a', second='2'}, 
Pair{first='a', second='3'}, Pair{first='b', second='4'}, 
Pair{first='b', second='5'}, Pair{first='b', second='6'}, Pair{first='c', second='7'}]

The Groovy and Ruby version are very expressive and concise. Note the use of the collectMany method on the Groovy version and the use of the flatten method on the Ruby version to flatten the result list into a single list of pairs.
The Java 8 version made use of the collect method of the Stream API, to collect the results in a list of Pair instances, each one holding the key and value of each element from the List< String >.

What do you think about this comparison? Leave your comments here!

Tags: , , , , , , ,

JavaCodeKata – Lambdas

I’ve came across that kata from @brjavaman and @yanaga to teach lambdas, one of the new features of JDK 8.

There are some unit tests to validate the solution. I’ve found it a good opportunity to exercise the use of lambdas so I decided to solve it. Below is my solution to this kata.

The first method should take the String list and sort all the String elements in ascending (ASCII) order:

/**
 * This method should take the String List and sort all the String elements in ascending (ASCII) order.
 *
 * @return The sorted values in ascending ASCII order.
 */
public List getSortedStrings() {
    return values.stream()
            .sorted()
            .collect(Collectors.toList());
}

The other method should take the String list and:

  1. filter the elements that contains one or more digits
  2. transform (map) the remaining Strings into Integers
  3. sort the Integers in ascending order
/**
 * This method should take the String List and:
 *
 * filter the elements that contains one or more digits;
 * transform (map) the remaining Strings into Integers;
 * sort the Integers in ascending order.
 *
 * @return
 */
public List getSortedIntegers() {
    return values.stream()
            .filter(s -> s.matches("\\d+"))
            .map(Integer::valueOf)
            .sorted()
            .collect(Collectors.toList());
}

The last method should take the String list and:

  1. filter the elements that contains one or more digits
  2. transform (map) the remaining Strings into Integers
  3. sort the Integers in descending order
/**
 * This method should take the String List and:
 *
 * filter the elements that contains one or more digits;
 * transform (map) the remaining Strings into Integers;
 * sort the Integers in descending order.
 *
 * @return
 */
public List getSortedDescendingIntegers() {
    return values.stream()
            .filter(s -> s.matches("\\d+"))
            .map(Integer::valueOf)
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());
}

Note that the steps filter the elements that contains one or more digits and transform (map) the remaining Strings into Integers are identical. So I decided to extract the partial Stream into a method with the Extract Method refactoring support on IntelliJ IDEA:

private Stream integersWithOneOrMoreDigits() {
    return values.stream()
            .filter(s -> s.matches("\\d+"))
            .map(Integer::valueOf);
}

Then I refactored the the solution to use the new extracted method:

public List getSortedIntegers() {
return integersWithOneOrMoreDigits()
.sorted()
.collect(Collectors.toList());
}
public List getSortedDescendingIntegers() {
return integersWithOneOrMoreDigits()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
}

I re-run the tests and they all passed. What do you think about this solution? Do you suggest other ones?