Results 1 to 2 of 2
  1. #1
    gunitinug is offline Member
    Join Date
    Dec 2016
    Posts
    13
    Rep Power
    0

    Default generic constructor

    Java Code:
    import java.util.*;
    
    // Define Box with data type D.
    public class Box<D> {
      D data;
      
      public <D> Box(D data) {
        this.data=data;
      }
      
      public D get() {
        return data;
      }
    }
    
    // Construct a list of boxes of data type D
    // And output the list to stdout.
    public class BoxUtility {
      // add Box<D> to the list of boxes
      public static <D> void addBox(D data, List<Box<D>> boxes) {
        Box<D> box=new Box<>(data);
        boxes.add(box);
      }
      
      // Output List<Box<D>> list of boxes to stdout.
      public static <D> void outputBoxes(List<Box<D>> boxes) {
        for (Box<D> b : boxes) {
          System.out.println(b.get());
        }
      }
      
      public static void main(String[] args) {
        // Create new boxes_list of box type String
        ArrayList<Box<String>> boxes_list = new ArrayList<>();
        // use addBox() to populate list
        addBox("apple",boxes_list);
        addBox("pear",boxes_list);
        addBox("banana",boxes_list);
        addBox("orange",boxes_list);
        // print out the list
        outputBoxes(boxes_list);
      }
    }
    This gives error
    /tmp/java_Xpr8Gp/Box.java:8: error: incompatible types: D#1 cannot be converted to D#2
    this.data=data;
    ^
    where D#1,D#2 are type-variables:
    D#1 extends Object declared in constructor <D#1>Box(D#1)
    D#2 extends Object declared in class Box
    1 error

    If I change contructor of Box to
    Java Code:
    public Box(D data) {
        this.data=data;
      }
    it works.

    My question is when should I use generic constructors and how?

    I guess type D of class cannot be guaranteed to be the same type D of constructor.
    The problem line is
    this.data=data;

    If I change it to
    Java Code:
    public <T> Box(D data) {
        this.data=data;
      }
    no errors.

    Got it!

    Actually
    Java Code:
    public <T> Box(D data, T data2) {
      ...
    }
    is more useful.
    Last edited by gunitinug; 05-09-2017 at 05:29 AM.

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: generic constructor

    First, your

    Why do you need a utility method to do the following:

    Java Code:
    boxes_list.add(new Box<>("apple"));
    And you may want to investigate lambdas and streams (requires Java 8)

    Java Code:
         // create the list
          List<Box<String>> boxes_list =
                Stream.of("apple", "pear", "peach", "banana", "orange").map(
                      Box<String>::new).collect(Collectors.toList());
    
          // print the contents
          boxes_list.stream().map(Box::get).forEach(System.out::println);
          
          
          System.out.println("----------------------------");
          // get and print only boxes where contents start with p
          Predicate<String> pFruit = (c) -> c.toLowerCase().charAt(0) == 'p';
          boxes_list.stream().map(Box::get).filter(pFruit).forEach(
                System.out::println);
    In the last example, the predicate could have been placed directly into the filter.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

Similar Threads

  1. Replies: 3
    Last Post: 05-23-2016, 04:53 PM
  2. Replies: 5
    Last Post: 08-11-2012, 09:50 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •