hotmeatballsoup
hotmeatballsoup

Reputation: 605

Implementing a generic container for a list of interface instances in Java

Java 8 here. I have the following POJOs:

public interface HasPartNumber {
  String getPartNumber();
}

@Getter
@Setter
public class InventoryItem implements HasPartNumber {
  private String modelNumber;
  private String description;
  // lots of other fields here

  @Override
  public String getPartNumber() {
    return this.modelNumber;
  }
}

public class Inventory extends ArrayList<InventoryItem> {
  // Inventory is just an alias of a list of InventoryItem
}

@Getter
@Setter
public class PriceItem implements HasPartNumber {
  private String equipmentNumber;
  // lots of other fields here

  @Override
  public String getPartNumber() {
    return this.equipmentNumber;
  }
}

public class PriceRoster extends ArrayList<PriceItem> {
  // PriceRoster is just an alias of a list of PriceItem
}

I understand some of you may have an aversion to how I'm modeling Inventory and PriceRoster, but using the is-a and has-a golden rule, it is correct. An "inventory" is no more and no less than just a list of InventoryItems. Ditto for PriceRoster. And, the Domain-Driven Design community would probably agree that these are valid data models if it makes sense to a developer reading the code.

However, I am not married to this design. And so while my druthers would be to keep this data model above, if it truly is impossible to accomplish what I describe below without changing the data model, I'll be flexible.


I am trying to write a generic PartProcessor class that will iterate through lists of HasPartNumber impls and perform processing on them. My best attempt:

public class PartProcessor<PART_CONTAINER extends List<HasPartNumber>> {

  public void process(PART_CONTAINER partContainer) {

    partContainer.stream().forEach(part -> {

      // Do something here

    });

  }

}

produces compilation errors when I go to instantiate the PartProcessor:

PartProcessor<Inventory> inventory = new PartProcessor<Inventory>();

The compiler errors I'm seeing are:

"Type parameter 'com.example.myapp.Inventory' is not within its bound; should implement 'java.util.List<com.example.myapp.HasPartNumber>'"

Any ideas what I can do to get my PartProcessor working generically on any list of HasPartNumbers impl, including Inventory and PriceRoster?

Upvotes: 2

Views: 637

Answers (1)

Eugene
Eugene

Reputation: 120848

bounded types makes the type covariant:

 public class PartProcessor<PART_CONTAINER extends List<? extends HasPartNumber>> {... 

For a broader read see this answer also.

Upvotes: 2

Related Questions