是否可能在Java中具有带有多个可选参数的通用方法

时间:2019-06-18 00:44:09

标签: java generics jaxb javax.xml

我的理解是,我的这个要求不可能直截了当。但我想找到一个可行的解决方案。

这就是我如何获得NamedNodeMap(javax package);的Iterable

private static Iterable<Node> iterableNamedNodeMap(NamedNodeMap namedNodeMap) {
        return () -> new Iterator<Node>() {

            private int index = 0;

            @Override
            public boolean hasNext() {
                return index < namedNodeMap.getLength();
            }

            @Override
            public Node next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                return namedNodeMap.item(index++);
            }
        };
}

这是NodeList(javax)的迭代

 private static Iterable<Node> iterableNamedNodeMap(NodeList nodeList) {
            return () -> new Iterator<Node>() {

                private int index = 0;

                @Override
                public boolean hasNext() {
                    return index < nodeList.getLength();
                }

                @Override
                public Node next() {
                    if (!hasNext())
                        throw new NoSuchElementException();
                    return nodeList.item(index++);
                }
            };
    }

由于除了参数外它们几乎相同, 我一直希望这样的事情,这当然是不对的。 NodeList和NamedNodeMap均未实现公共接口。那么什么是最好的方法呢?

private static <T extends NodeList | NamedNodeMap> Iterable<Node> iterableNamedNodeMap(T in) {
        return () -> new Iterator<Node>() {

            private int index = 0;

            @Override
            public boolean hasNext() {
                return index < in.getLength();
            }

            @Override
            public Node next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                return in.item(index++);
            }
        };

1 个答案:

答案 0 :(得分:1)

您可以通过创建一个工厂方法来减少一些样板,该方法接受两个使用NodeListNamedNodeMap的功能接口,并使用方法引用:

private static Iterable<Node> iterableNodes(
    Supplier<int> lengthGetter,
    Function<int, Node> itemGetter
) {
     return () -> new Iterator<Node>() {
        private int index = 0;

        @Override
        public boolean hasNext() {
            return index < lengthGetter.get();
        }

        @Override
        public Node next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return itemGetter.apply(index++);
        }
    };
}

private static Iterable<Node> iterableNamedNodeMap(NamedNodeMap namedNodeMap) {
    return iterableNodes(namedNodeMap::getLength, namedNodeMap::item);
}

private static Iterable<Node> iterableNodeList(NodeList nodeList) {
    return iterableNodes(nodeList::getLength, nodeList::item);
}