zoukankan      html  css  js  c++  java
  • golang list使用 双层 循环 删除 遍历

    queue队列:

    import (
        "container/list"
        "sync"
    )
    
    type Queue struct {
        l *list.List
        m sync.Mutex
    }
    
    func NewQueue() *Queue {
        return &Queue{l: list.New()}
    }
    
    func (q *Queue) PushBack(v interface{}) {
        if v == nil {
            return
        }
        q.m.Lock()
        defer q.m.Unlock()
        q.l.PushBack(v)
    }
    
    func (q *Queue) Front() *list.Element {
        q.m.Lock()
        defer q.m.Unlock()
        return q.l.Front()
    }
    
    func (q *Queue) Remove(e *list.Element) {
        if e == nil {
            return
        }
        q.m.Lock()
        defer q.m.Unlock()
        q.l.Remove(e)
    }
    
    func (q *Queue) Len() int {
        q.m.Lock()
        defer q.m.Unlock()
        return q.l.Len()
    }
    

    这样就基本满足了.

    使用过程中, 发现list有个小坑: 遍历的时候不能Remove

    for e := l.Front(); e != nil; e = e.Next {
        l.Remove(e)
    }
    

    按照设想, 这应该会移除list里所有的元素, 但是, 结果是只移除了第一个. 原因是: Remove时候, e.next = nil, 使得for判断中, e != nil不成立了, 所以退出了循环.
    这时候有两种解决办法:

    var next *list.Element
    for e := l.Front(); e != nil; e = next {
        next = e.Next()
        l.Remove(e)
    }
    
    for {
        e := l.Front()
        if e == nil {
                break
        }
        l.Remove(e)
    }

    如果是双层循环删除的话, 注意如果第二个循环删除的元素在第一个删除的元素后一位, 需要再前进一位:
    if j == nexte {
    nexte = nexte.Next()
    }
     
  • 相关阅读:
    jquery跨域3
    juery的跨域请求2
    jquery的跨域请求
    synchronized与Lock的区别
    springboot之启动原理解析及源码阅读
    java中Number类理解
    springboot中配置文件application.properties的理解
    restTemplate设置访问超时
    BigDecimal.setScale 处理java小数点
    NIO之FileChannel类的理解和使用
  • 原文地址:https://www.cnblogs.com/mafeng/p/10794859.html
Copyright © 2011-2022 走看看