簡體   English   中英

獲取對象類並用作通用構造函數的參數

[英]Get object class and use as argument for generic constructor

我敢肯定,這已經被問過了,但是我是Java的新手,也不熟悉我要尋找的確切術語。

我有一個BST課程:

public class BinarySearchTree<T extends Comparable> {
    /* ... */
}

然后我為此編寫了一些測試:

public static void main(String[] args) {
    Integer[] integerItems = {1, 7, 8, 2, -1, -10, 100, 12, 32};
    String[] stringItems = {"jungi", "phil", "bob", "leslie", "tyler", "clarence"};
    Comparable[][] comparableLists = {integerItems, stringItems};

    for (Comparable[] list : comparableLists) {
        BinarySearchTree<>...
    }
}

我對這一步感到困惑。 如何從列表中恢復類型(String [],Integer []等)並將其用作參數? 我想要這樣的東西:

for (Comparable[] list : comparableLists) {
    BinarySearchTree<typeOf(list)> root = new BinarySearchTree<typeOf(list)>();
    /* ... tests ... */
}

我在這里找到的一個選擇只是列出所有可能的受支持類型。 這似乎很愚蠢,因為我不知道所有受支持的類型。 也許這些類型會改變,等等。但是我已經對其進行了硬編碼。

我該如何應對呢?

編輯:

因此,更具體一點,這是BST實現:

public class BinarySearchTree<T extends Comparable> {
    private T value;
    private BinarySearchTree<T> leftChild;
    private BinarySearchTree<T> rightChild;

    public BinarySearchTree() {

    }

    public BinarySearchTree(T v) {
        value = v;
        createChildren();
    }

    public void createChildren() {
        leftChild = new BinarySearchTree<T>();
        rightChild = new BinarySearchTree<T>();
    }

    public void insert(T v) {
        if (value == null) {
            value = v;
            createChildren();
        } else if (v < value) {
            leftChild.insert(v);
        }
        rightChild.insert(v);
    }

    public boolean valueExists(T v) {
        if (value == null) {
            return false;
        } else if (value == v) {
            return true;
        } else if (v < value) {
            return leftChild.valueExists(v);
        }
        return rightChild.valueExists(v);
    }

    public String toString() {
        String bstStringBuilder = "";

        if (value == null) {
            return "";
        }

        bstStringBuilder += leftChild + " ";
        bstStringBuilder += value + " ";
        bstStringBuilder += rightChild;
        return bstStringBuilder;
    }
}

如果我使用@OldCurmudgeon的建議,main()如下所示:

public static void main(String[] args) {
    Integer[] integerItems = {1, 7, 8, 2, -1, -10, 100, 12, 32};
    String[] stringItems = {"jungi", "phil", "bob", "leslie", "tyler", "clarence"};
    Comparable[][] comparableLists = {integerItems, stringItems};

    for (Comparable[] list : comparableLists) {
        BinarySearchTree<Comparable> root = new BinarySearchTree<Comparable>();

        for (Comparable item : list) {
            root.insert(item);
        }

        System.out.println(root);
    }
}

這將產生以下編譯器錯誤:

BinarySearchTree.java:26: error: bad operand types for binary operator '<'
    } else if (v < value) {
                 ^
first type:  T
second type: T
where T is a type-variable:
  T extends Comparable declared in class BinarySearchTree
  BinarySearchTree.java:37: error: bad operand types for binary operator '<'
      } else if (v < value) {
                 ^
first type:  T
second type: T
where T is a type-variable:
  T extends Comparable declared in class BinarySearchTree
2 errors

也許這更有幫助?

通用方法進行救援!

看:

class BinarySearchTree<T extends Comparable<T>> {
    void put(T item) {}
}

class Test {

    public static <T extends Comparable<T>> void putIntoATree(BinarySearchTree<T> tree, T[] items) {
        for (T item : items)
            tree.put(item);
    }

    public static void main(String[] args) {

        Integer[] integerItems = {1, 7, 8, 2, -1, -10, 100, 12, 32};
        BinarySearchTree<Integer> integerTree = new BinarySearchTree<>();
        putIntoATree(integerTree, integerItems);

        String[] stringItems = {"jungi", "phil", "bob", "leslie", "tyler", "clarence"};
        BinarySearchTree<String> stringTree = new BinarySearchTree<>();
        putIntoATree(stringTree, stringItems);

    }

}

如您的示例所示,存在具有泛型類型的數組通常會在某個地方強制轉換(或留下“未經檢查”的警告)。 這就是為什么我避免在示例中使用數組的原因。

消除類型轉換並使代碼類型安全的一種方法是將數組包裝到一個通用類中,這將使javac滿意:

class BinarySearchTree<T extends Comparable<T>> {
    void put(T item) {}
}

class Test {

    public static <T extends Comparable<T>> void putIntoATree(BinarySearchTree<T> tree, T[] items) {
        for (T item : items)
            tree.put(item);
    }

    private static class ArrayAndATree<T extends Comparable<T>> {
        final T[] contents;
        final BinarySearchTree<T> aTree;

        private ArrayAndATree(T[] contents) {
            this.contents = contents;
            aTree = new BinarySearchTree<>();
        }
    }
    public static void main(String[] args) {

        Integer[] integerItems = {1, 7, 8, 2, -1, -10, 100, 12, 32};
        String[] stringItems = {"jungi", "phil", "bob", "leslie", "tyler", "clarence"};

        ArrayAndATree<Integer> integerArrayAndATree = new ArrayAndATree<>(integerItems);
        ArrayAndATree<String> stringArrayAndATree = new ArrayAndATree<>(stringItems);

        ArrayAndATree<?> taggedArrays[] = {integerArrayAndATree, stringArrayAndATree};
        for (ArrayAndATree<?> a : taggedArrays) {
            putIntoATree(a.aTree, a.contents);
            process(a);
        }
    }

    private static <T extends Comparable<T>> void process(ArrayAndATree<T> a) {
        putIntoATree(a.aTree, a.contents);
    }
}

這是對多個類型的對象使用通用接口的關鍵所在。 使用Comparable

    for (Comparable[] list : comparableLists) {
        BinarySearchTree<Comparable> tree = ...

您無需在運行時知道具體類型,泛型將在編譯時應用。

因此,您可以在代碼中執行以下操作:

public static void main(String[] args) {
    Integer[] integerItems = {1, 7, 8, 2, -1, -10, 100, 12, 32};
    String[] stringItems = {"jungi", "phil", "bob", "leslie", "tyler", "clarence"};
    Comparable[][] comparableLists = {integerItems, stringItems};

    for (Comparable[] list : comparableLists) {
        BinarySearchTree b = BinarySearchTree.class.newInstance();
        for (Object element : list) {
            b.add(element); // or whatever method you want to use
        }
    }
}

您只需要注意現在不要使用錯誤的類型,因為編譯器沒有提供任何指導

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM