uma
uma

Reputation: 1577

How to Write a Comparator to Generalize two types of Objects in Java?

I used the following method call to return a List of Objects.

final List<LinkModelSpi> documentLinks = this.documentLinksModelSpi.getDocumentLinks(); 

Next I used a Comparator to sort this list. But List contain Two types of object. Some functionally works it Return DocumentLinkModelImpl and some function operations it return LinkModelImpl.So , Comparator function passed Class Cast exception when LinkModelImple change to DocumentLinkModelImpl .This both object parent type also deference.

// Add This method for Sorting Document Link View Same Order. Now The application display same links order
// in catalogue administration edit drug window
Collections.sort(documentLinks,
    (Comparator<? super LinkModelSpi>) new Comparator<DocumentLinkModelImpl>() {
      @Override
      public int compare(DocumentLinkModelImpl o1, DocumentLinkModelImpl o2) {
        return o1.getResource().compareTo(o2.getResource());
      }

      /*@Override
      public int compare(LinkModelImpl o1,LinkModelImpl o2) {
        return o1.getResource().compareTo(o2.getResource());
      }*/

});

I need some expert help to resolve the matter?

Note: I added above sort method newly, but before I added it, the method executed well for all objects.

final List<LinkModelSpi> documentLinks = this.documentLinksModelSpi.getDocumentLinks();

for (final LinkModelSpi documentLinkModelSpi : documentLinks)
{
  //noinspection unchecked
  ((DtoPresentationModelSpi<?, MDTO>) documentLinkModelSpi).addPropertyChangeListener(this);
}

--------------ERROR----------------------

Presentation.impl.LinkModelImpl cannot be cast to Presentation.impl.DocumentLinkModelImpl
    at Client.catadmin.view.component.AbstractEditLinkDialog$1.compare(AbstractEditLinkDialog.java:171)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
    at java.util.TimSort.sort(TimSort.java:220)

Upvotes: 0

Views: 296

Answers (2)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31269

Let me be clearer what I mean with my comment. If both DocumentLinkModelImpl and LinkModelImpl have a method getResource, then chances are that the supertype (can't see if it's an interface implemented by both or a superclass) LinkModelSpi has a method getResource as well. So then you can just write:

Collections.sort(documentLinks,
    new Comparator<LinkModelSpi>() {
      @Override
      public int compare(LinkModelSpi o1, LinkModelSpi o2) {
        return o1.getResource().compareTo(o2.getResource());
      }
});

Even if that's not the case, you can work it out:

Collections.sort(documentLinks,
    new Comparator<LinkModelSpi>() {
      @Override
      public int compare(LinkModelSpi o1, LinkModelSpi o2) {
        String resource1, resource2; // String or whatever type the getResource method returns
        if (o1 instanceof DocumentLinkModelImpl) {
            resource1 = ((DocumentLinkModelImpl)o1).getResource();
        } else if (o1 instanceof LinkModelImpl) {
            resource1 = ((LinkModelImpl)o1).getResource();
        } else {
            throw new IllegalArgumentException();
        }
        if (o2 instanceof DocumentLinkModelImpl) {
            resource2 = ((DocumentLinkModelImpl)o2).getResource();
        } else if (o2 instanceof LinkModelImpl) {
            resource2 = ((LinkModelImpl)o2).getResource();
        } else {
            throw new IllegalArgumentException();
        }
        return resource1.compareTo(resource2);
      }
});

(of course you'd factor the instanceof checking into its own method to clean up that code)

Upvotes: 3

uma
uma

Reputation: 1577

I resolve above trouble adding this code fragment. But I need to know some , more Advanced solution , if know any one.

if (Checks.checkNotNullAndNonEmpty(documentLinks)) {
  if (this.documentLinksModelSpi.getDocumentLinks().iterator().next() instanceof DocumentLinkModelSpi) {

  } else {

  }
}

Upvotes: 0

Related Questions