自定义类型的集合判断是否包含某个子项

在我们项目中有这么一个场景,有一个树型结构的字典列表,需要实现多选功能。我的实现思路呢,是自定义了一个DictIndexPath下标类,里面包含两个属性:行section、列row,然后通过一个List来存储选择的下标类。

// 下标类
class DictIndexPath {
  int section;
  int row;

  DictIndexPath(this.section, this.row);

  @override
  String toString() {
    return 'section: $section, row: $row';
  }
}

// 存储
List _selectTemp = [];

然后在选择字典项的时候,根据树形结构计算行列的值,然后判断是否选中:

int section = ...
int row = ...
DictIndexPath indexPath = DictIndexPath(section, row);
if (_selectTemp.contains(indexPath)) {
    _selectTemp.remove(indexPath);
} else {
    _selectTemp.add(indexPath);
}

但是呢,理想很丰满,现实很骨感,这么做并不能实现我想要的效果。结果呢会发现contains方法返回的一直都是false,从而重复添加到_selectTemp里面。

这是因为DictIndexPath在初始化的时候会生成一个唯一的hashCode,虽然section和row是一样的,但是hashCode不同,导致生成的每一个indexPath都是不一样的。

所以呢要重写hashCode的获取方法,使相同的section和row的时候,hashCode保持一致。下面是我所采用的方式:

@override
int get hashCode {
    return section * 100 + row;
}

但是呢,在选择字典项的时候还是不行,还是会重复添加。

于是就想着是不是contains方法的原因。通过查看源码发现,contains方法很简单,就是遍历集合,然后判断是否相等。

bool contains(Object? element) {
    for (E e in this) {
      if (e == element) return true;
    }
    return false;
  }

于是就想起曾经看过的文章,需要重写==操作符,来实现判断两个对象是否相等。想起来就干啊,于是就在DictIndexPath类中增加了我自己的操作符重载。

operator ==(other) {
    if (other is! DictIndexPath) {
      return false;
    }
    return section == other.section && row == other.row;
}

再次尝试选择字典项,终于实现目标了。

最终的DictIndexPath类如下:

class DictIndexPath {
  int section;
  int row;

  DictIndexPath(this.section, this.row);

  @override
  String toString() {
    return 'section: $section, row: $row';
  }

  @override
  int get hashCode {
    return section * 100 + row;
  }

  operator ==(other) {
    if (other is! DictIndexPath) {
      return false;
    }
    return section == other.section && row == other.row;
  }
}

你可能感兴趣的:(自定义类型的集合判断是否包含某个子项)