【问题标题】:Don't understand Java class definition containing an iterable of itself.不理解包含自身可迭代的 Java 类定义。
【发布时间】:2015-05-18 23:50:32
【问题描述】:

我在我们的 java 项目中遇到了一个让我难以理解的类。 它使用类型参数实现 Iterable 接口,因为它是该可迭代对象的自身。有人能解释一下它的作用以及它为什么有用吗?

public class IndexRequest extends Request implements Cloneable, Iterable<IndexRequest> {
    public enum OpType {insert, update};

    protected Index index;
    protected Type type;
    protected boolean incomingAsArray;
    protected long timeToLive;
    protected String parent;
    protected String route;
    protected LinkedListMultimap<String, IndexRequest> iterable;
    protected String errorMessage;
    protected String stackTrace;
    protected String warnMessage;
    protected OpType opType = OpType.insert;
    protected long versionId;
    protected JsonNode previousDocument;
    protected boolean ignored;
    protected String resultCode;
    protected int retries = 0;
    protected boolean esUpsertFlag = false;
    protected String id = UUID.randomUUID().toString();


    /**
     * Constructor
     */
    public IndexRequest() {
        super();
        logger = LoggerFactory.getLogger(IndexRequest.class);
        this.requestJson = JsonNodeFactory.instance.arrayNode();
    }


    /**
     * Constructor
     */
    public IndexRequest(String endpointPath, String requestId, String user, JsonNode requestJson, Map<String, String[]> requestParameters) {
        super(endpointPath, requestId, user, requestJson, requestParameters);
    }

    /**
     * Initialize our iterable version of this class
     */
    protected void initIterable() {
LinkedListMultimap <String, IndexRequest> contents = LinkedListMultimap.create();
        if (isArray()) {
            ArrayNode docsArray = (ArrayNode) getDocument();
            Iterator<JsonNode> docIterator = docsArray.iterator();
            while (docIterator.hasNext()) {
                IndexRequest is = this.clone(false);
                // generate a new id since this is a new wrapper around a particular doc
                is.id = UUID.randomUUID().toString();
                is.setDocument(docIterator.next());
                contents.put(is.getId(), is);
            }

            iterable = contents;
        }
        else {
            iterable = LinkedListMultimap.create();                     
            iterable.put(getId(), this);
        }
    }

    /**
     * Returns an iterator for this index set
     * @return Iterator<IndexRequest> An iterator for this index set
     */
    public Iterator<IndexRequest> iterator() {
        if (iterable == null) {
            initIterable();
        }
        return iterable.values().iterator();
    }
}

提前谢谢你。

【问题讨论】:

  • 它看起来像递归结构,因此迭代其子/子部分是有意义的。并使其成为iterable 例如。允许它参与 foreach 循环。

标签: java generics iterable


【解决方案1】:

这个类看起来像是在这样的节点树中定义了一个节点。实例持有从Strings 到同一类的其他实例的映射:

    protected LinkedListMultimap<String, IndexRequest> iterable;

它们还从其父类继承了某种存在/持有其他实例数组的感觉。当它们被迭代时,它们会从它们的映射或数组的元素中提供值。

【讨论】:

    【解决方案2】:

    实现 Iterable 的类可以与新的 for 循环一起使用。这是一个这样的例子:

    List list = new ArrayList();
    
    for(Object o : list){
        //do something o;    
    }
    

    Iterable 接口只有一种方法:

    public interface Iterable<T> {
      public Iterator<T> iterator();    
    }
    

    可以通过新的 for 循环使用我们自己的集合类型类。为此,我们的类必须实现 java.lang.Iterable 接口。并提供iterator 方法的实现,你可以在你的类中看到这里提供了:

      /**
         * Returns an iterator for this index set
         * @return Iterator<IndexRequest> An iterator for this index set
         */
        public Iterator<IndexRequest> iterator() {
            if (iterable == null) {
                initIterable();
            }
            return iterable.values().iterator();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多