Go语言之自定义集合Set

2020-01-28 12:04:18丽君

对称差集


// 生成集合 one 和集合 other 的对称差集
func (set *HashSet) SymmetricDifference(other *HashSet) *HashSet {
  if set == nil || other == nil {// set和other都为nil,则它们的对称差集为nil
    return nil
  }
  diffA := set.Difference(other)//生成集合 set 对集合 other 的差集
  if other.Len() == 0 {//如果other的元素数量等于0,那么other对集合set的差集为空,则直接返回diffA
    return diffA
  }
  diffB := other.Difference(set)//生成集合 other 对集合 set 的差集
  return diffA.Union(diffB)//返回集合 diffA 和集合 diffB 的并集
}

4.进一步重构
目前所实现的 HashSet 类型提供了一些必要的集合操作功能,但是不同应用场景下可能会需要使用功能更加丰富的集合类型。当有多个集合类型的时候,应该在它们之上抽取出一个接口类型以标识它们共有的行为方式。依据 HashSet 类型的声明,可以如下声明 Set 接口类型:


type Set interface {
  Add(e interface{}) bool
  Remove(e interface{})
  Clear()
  Contains(e interface{}) bool
  Len() int
  Same(other Set) bool
  Elements() []interface{}
  String() string
}

注意: Set 中的 Same 方法的签名与附属于 HashSet类型的 Same 方法有所不同。这里不能再接口类型的方法的签名中包含它的实现类型。因此这里的改动如下:


func (set *HashSet) Same(other Set) bool {
  //省略若干语句
}

修改了 Same 方法的签名,目的是让 *HashSet 类型成为 Set 接口类型的一个实现类型。

高级功能的方法应该适用于所有的实现类型,完全可以抽离出成为独立的函数。并且,也不应该在每个实现类型中重复地实现这些高级方法。如下为改造后的 IsSuperset 方法的声明:


// 判断集合 one 是否是集合 other 的超集
// 读者应重点关注IsSuperset与附属于HashSet类型的IsSuperset方法的区别
func IsSuperset(one Set, other Set) bool {
  if one == nil || other == nil {
    return false
  }
  oneLen := one.Len()
  otherLen := other.Len()
  if oneLen == 0 || oneLen == otherLen {
    return false
  }
  if oneLen > 0 && otherLen == 0 {
    return true
  }
  for _, v := range other.Elements() {
    if !one.Contains(v) {
      return false
    }
  }
  return true
}

以上就是Go语言之自定义集合Set的全部内容,希望对大家学习Go语言有所帮助。