flutter的ObserverList和HashedObserverList

ObserverList和HashedObserverList这两个类是在observer_list.dart这个文件里的,还是使用频率很高的两个封装的小工具。

这两个class主要是在某些场景用来替代list这个数据类型的,这个某个场景就是你调用contains方法的频率远远多余add和remove这两个方法,即就是针对contains做了一个定向的性能优化。

那ObserverList和HashedObserverList在使用场景上有什么区别呢?就是list长度比较大时用HashedObserverList,比较小时用ObserverList。

来看一下ObserverList内部实现:

class ObserverList extends Iterable {
  final List _list = [];
  bool _isDirty = false;
  HashSet _set;

  /// Adds an item to the end of this list.
  ///
  /// This operation has constant time complexity.
  void add(T item) {
    _isDirty = true;
    _list.add(item);
  }

  /// Removes an item from the list.
  ///
  /// This is O(N) in the number of items in the list.
  ///
  /// Returns whether the item was present in the list.
  bool remove(T item) {
    _isDirty = true;
    _set?.clear(); // Clear the set so that we don't leak items.
    return _list.remove(item);
  }

  @override
  bool contains(Object element) {
    if (_list.length < 3)
      return _list.contains(element);

    if (_isDirty) {
      if (_set == null) {
        _set = HashSet.from(_list);
      } else {
        _set.addAll(_list);
      }
      _isDirty = false;
    }

    return _set.contains(element);
  }

  @override
  Iterator get iterator => _list.iterator;

  @override
  bool get isEmpty => _list.isEmpty;

  @override
  bool get isNotEmpty => _list.isNotEmpty;
}

还是挺一目了然的,就是把list转换成set来做contains查询,当list调用了remove和add方法时,利用标志位_isDirty做标记,并在contains方法需要的时候重新转化成set做成懒处理方式,这样是性能最优的实现。

HashedObserverList的内部实现代码如下:

class HashedObserverList extends Iterable {
  final LinkedHashMap _map = LinkedHashMap();

  /// Adds an item to the end of this list.
  ///
  /// This has constant time complexity.
  void add(T item) {
    _map[item] = (_map[item] ?? 0) + 1;
  }

  /// Removes an item from the list.
  ///
  /// This operation has constant time complexity.
  ///
  /// Returns whether the item was present in the list.
  bool remove(T item) {
    final int value = _map[item];
    if (value == null) {
      return false;
    }
    if (value == 1) {
      _map.remove(item);
    } else {
      _map[item] = value - 1;
    }
    return true;
  }

  @override
  bool contains(Object element) => _map.containsKey(element);

  @override
  Iterator get iterator => _map.keys.iterator;

  @override
  bool get isEmpty => _map.isEmpty;

  @override
  bool get isNotEmpty => _map.isNotEmpty;
}

这个类内部就是通过LinkedHashMap来实现的,这个的内部就更简单一些,即list里的每一个item就是key,value就是key的实际数量。很简单直白。

这是flutter框架源码分析的其中一篇,因能力有限,有诸多不足之处,还请斧正。

你可能感兴趣的:(flutter的ObserverList和HashedObserverList)