0

I'm trying to rewrite this code from an answer to generic ArrayList extension in Kotlin.

public  boolean equalLists(List<String> one, List<String> two){     
    if (one == null && two == null){
        return true;
    }

    if((one == null && two != null) 
      || one != null && two == null
      || one.size() != two.size()){
        return false;
    }

    //to avoid messing the order of the lists we will use a copy
    //as noted in comments by A. R. S.
    one = new ArrayList<String>(one); 
    two = new ArrayList<String>(two);   

    Collections.sort(one);
    Collections.sort(two);      
    return one.equals(two);
}

I came up with the code below but I'm getting Unresolved reference: T

fun ArrayList<T>.equalLists(one: ArrayList<T>?, two: ArrayList<T>?): Boolean {
    if (one == null && two == null) {
        return true
    }

    if (one == null && two != null || one != null && two == null || one?.size != two?.size) {
        return false
    }

    val oneCopy = ArrayList(one)
    val twoCopy = ArrayList(two)

    oneCopy.sort()
    twoCopy.sort()

    return one == two
}

How to properly implement this in Kotlin?

Philip Borbon
  • 707
  • 1
  • 11
  • 21

3 Answers3

2

I see that you found a workable solution, but I believe a more Kotlin-idiomatic solution would be to define this on the List interface itself, rather than ArrayList specifically, and can also be declared as an extension on nullable List references to be equivalent to the original Java code (which supported two null lists as arguments):

fun <T : Comparable<T>> List<T>?.containsSameElementsAs(other: List<T>?) = when {
    (this == null) xor (other == null) -> false // if only one is null
    (this?.size != other?.size) -> false // if both null, or have different sizes
    (this?.size == 1) -> this == other // avoid allocations for single element
    else -> this?.sorted() == other?.sorted()
}

Might also be worth considering using a Set instead if the order is not important and duplicates aren't meaningful.

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
0

Below is the example of Generics in kotlin

First created custom pojo class named as Product:

public class Product implements Serializable {

    int id;
    String mName;

    public Product(int id, String mName) {
        this.id = id;
        this.mName = mName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getmName() {
        return mName;
    }

    public void setmName(String mName) {
        this.mName = mName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return id == product.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

Then add below code in onCreate() method:

val p1 = Product(1, "abc")
val p2 = Product(2, "abc")
val p3 = Product(3, "abc")
val p4 = Product(4, "abc")
val p5 = Product(5, "abc")

val p11 = Product(1, "abc")
val p22 = Product(12, "sdg")
val p33 = Product(3, "xfg")
val p44 = Product(14, "pqr")
val p55 = Product(5, "fhtryt")

val mProduList1 = ArrayList<Product>()
val mProduList2 = ArrayList<Product>()

mProduList1.add(p1)
mProduList1.add(p2)
mProduList1.add(p3)
mProduList1.add(p4)
mProduList1.add(p5)


mProduList2.add(p11)
mProduList2.add(p22)
mProduList2.add(p33)
mProduList2.add(p44)
mProduList2.add(p55)

equalLists(mProduList1, mProduList2)

Then create generic function named as "equalLists":

public fun equalLists(one: ArrayList<*>?, two: ArrayList<*>?): Boolean {
    if (one == null && two == null) {
    return true
}

if (one == null && two != null || one != null && two == null || one?.size != two?.size) {
    return false
}

val oneCopy = ArrayList(one)
val twoCopy = ArrayList(two)

sortProduct(oneCopy)
sortProduct(twoCopy)


return one == two

}

Then create new function that will cast generic type to product and then sort them:

private fun sortProduct(dummyCopy: ArrayList<Any>) {
    (dummyCopy as ArrayList<Product>).sortWith(object: Comparator<Product>{
        override fun compare(p1: Product, p2: Product): Int = when {
            p1.id > p2.id -> 1
            p1.id == p2.id -> 0
            else -> -1
        }
    })

    for(i in dummyCopy){
        Log.e("tagMine", "i.id is " + i.id + " i.mName " + i.mName)
    }
}

To define generic function we can choose one of the follwing like use "<*>" or can use "fun<T>" as below:

1) public fun equalLists(one: ArrayList<*>?, two: ArrayList<*>?): Boolean {

2) fun<T> equalLists(one: ArrayList<T>?, two: ArrayList<T>?): Boolean {

android
  • 2,942
  • 1
  • 15
  • 20
0

Finally came up with generic ArrayList extension for this.

fun <T: Comparable<T>> ArrayList<T>.equalLists(other: ArrayList<T>?): Boolean {
    if (other == null) {
        return true
    }

    if ( size != other.size ) {
        return false
    }

    val thisCopy = ArrayList(this)
    val otherCopy = ArrayList(other)

    thisCopy.sort()
    otherCopy.sort()


    return thisCopy == otherCopy
}

Usage:

categories.equalLists(otherCategories)
Philip Borbon
  • 707
  • 1
  • 11
  • 21