Monday, February 5, 2018

Maven version sorting with Java 8

You can easily sort versions in Maven using org.apache.maven.artifact.versioning.ComparableVersion :

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.pierre</groupId>
  <artifactId>mavensort</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
   <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-artifact</artifactId>
    <version>3.5.2</version>
   </dependency>
  </dependencies>
</project>

package mavensort;

import org.apache.maven.artifact.versioning.ComparableVersion;

public class Artifact implements Comparable<Artifact> {
 int id;
 String version;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getVersion() {
  return version;
 }
 public void setVersion(String version) {
  this.version = version;
 }
 public Artifact(int id, String version) {
  super();
  this.id = id;
  this.version = version;
 }

 public int compareTo(Artifact o) {
  
  ComparableVersion cv1 = new ComparableVersion(version);
  ComparableVersion cv2 = new ComparableVersion(o.getVersion());
  int compareTo = cv1.compareTo(cv2);
  System.out.println("compareTo " + version + " " + o.getVersion() + " " + compareTo);
  return compareTo;
 }
 

}


package mavensort;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.maven.artifact.versioning.ComparableVersion;
import org.junit.Test;

public class ArtifactTest {

 @Test
 public void testSort() {
  String version1 = "1.2";
  ComparableVersion cv1 = new ComparableVersion(version1);
  String version2 = "1.12";
  ComparableVersion cv2 = new ComparableVersion(version2);
  assert(cv1.compareTo(cv2) < 0);

 }
 
 @Test
 public void testSortCollection() {
  Artifact a1 = new Artifact(1, "1.2");
  Artifact a2 = new Artifact(2, "1.12");
  Artifact a3 = new Artifact(3, "0.12");
  List<Artifact> list = Arrays.asList(a1, a2, a3);
  Supplier<List<Artifact>> supplier = () -> new ArrayList<Artifact>();
  List<Artifact> sortedList = list.stream().sorted().collect(Collectors.toCollection(supplier));
  sortedList.forEach(item -> System.out.println(item.version));
  
 }

}


The use of streams and Supplier just to sort a collection is voodoistic. One can simply code this:

Collections.sort(list);
list.forEach(item -> System.out.println(item.version));


You can use also an external comparator:

@Test
 public void testSortCollectionExternalComparator() {
  Artifact a1 = new Artifact(1, "1.2");
  Artifact a2 = new Artifact(2, "1.12");
  Artifact a3 = new Artifact(3, "0.12");
  List<Artifact> list = Arrays.asList(a1, a2, a3);
  list.sort(new ArtifactComparator());
  list.forEach(item -> System.out.println(item.version));
  
 }


public class ArtifactComparator implements Comparator<Artifact> {

 @Override
 public int compare(Artifact o1, Artifact o2) {
  ComparableVersion cv1 = new ComparableVersion(o1.getVersion());
  ComparableVersion cv2 = new ComparableVersion(o2.getVersion());
  int compareTo = cv1.compareTo(cv2);
  System.out.println("C2 compareTo " + o1.getVersion() + " " + o2.getVersion() + " " + compareTo);
  return compareTo;
 }

}




The external dependency is not necessary, you can simply copy the class https://raw.githubusercontent.com/apache/maven/master/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java into your project, luckily it has no other dependencies to other classes in the same package

Ref: https://www.geeksforgeeks.org/collections-sort-java-examples/ for comparators



No comments: