joda-collection官網(wǎng)說明了是提供jdk和guava之外的collection操作亿傅,所以提供了Grid操作;
Grid顧名思義就是網(wǎng)格的意思,也就是有個(x,y)坐標(biāo)確定一個元素;
如何引入
現(xiàn)在基本都是采用maven構(gòu)建方式潜圃,在需要的項目pom中添加依賴:
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-collect</artifactId>
<version>0.7</version>
</dependency>
源碼解析
繼承關(guān)系
-
Grid
定義為接口,AbstractGrid
為實現(xiàn)該接口的抽象類 -
DenseGrid
舟茶,ImmutableGrid
(抽象類)谭期,SparseGrid
均實現(xiàn)了AbstractGrid
抽象類 -
DenseImmutableGrid
,EmptyGrid
吧凉,SingletonGrid
隧出,SparseImmutableGrid
實現(xiàn)了Immutable
抽象類 - 其中
AbstractGrid
,DenseImmutableGrid
客燕,EmptyGrid
鸳劳,SingletonGrid
和SparseImmutableGrid
為包訪問權(quán)限
看代碼
ImmutableGrid的copyOf方法
該方法為從grid獲取到具有immutable
的grid
public static <R> ImmutableGrid<R> copyOf(Grid<R> grid) {
if (grid == null) {
throw new IllegalArgumentException("Grid must not be null");
}
if (grid instanceof ImmutableGrid) {
return (ImmutableGrid<R>) grid;
}
validateCounts(grid.rowCount(), grid.columnCount
if (grid.size() == 0) {
return new EmptyGrid<R>(grid.rowCount(), grid.columnCount());
}
if (grid.size() == 1) {
Cell<R> cell = grid.cells().iterator().next();
return new SingletonGrid<R>(grid.rowCount(), grid.columnCount(), cell);
}
if (grid.size() >= (grid.rowCount() * grid.columnCount() / 2)) {
return DenseImmutableGrid.create(grid);
}
return new SparseImmutableGrid<R>(grid);
}
- 如果grid為空的,那么返回EmptyGrid也搓;其實返回這個用處不大赏廓,本來就是個immutable的涵紊,不能往里插數(shù)據(jù)
- 如果grid所持有的對象個數(shù)為1,那么返回的是SingletonGrid幔摸;
- 如果grid所持有的對象個數(shù)大于等于grid總大小的一般摸柄,就用DenseImmutableGrid(非稀疏的不可變grid),否則返回的是SparseImmutableGrid(稀疏的不可變grid)
關(guān)于稀疏(dense)grid和非稀疏(sparse)grid
兩者的區(qū)別在于存儲的方式不同:dense采用的的數(shù)組的方式存儲信息既忆,而sparse采用
SortedSet<Cell<V>>
來作為存儲結(jié)構(gòu)驱负;下邊先介紹Cell是什么玩意
Cell接口是Grid的一個內(nèi)部接口,MutableCell和ImmutableCell采用相同的存儲結(jié)構(gòu)且都實現(xiàn)AbstractCell抽象類患雇,存儲結(jié)構(gòu)為row跃脊,column,value
接下來看看SparseGrid的實現(xiàn)
private final int rowCount;
private final int columnCount;
private final SortedSet<Cell<V>> cells;
public static <R> SparseGrid<R> create(int rowCount, int columnCount) {
return new SparseGrid<R>(rowCount, columnCount, new TreeSet<Cell<R>>(AbstractCell.<R>comparator()));
}
首先苛吱,通過SortedSet來存儲酪术,在creat方法中可以看到,實際采用的是SortedSet的實現(xiàn)類TreeSet來存儲翠储;然后存儲總行數(shù)和總列數(shù)绘雁;為什么不直接聲明為TreeSet來存儲呢,主要是為了擴(kuò)展性考慮援所,面向接口編程嘛庐舟;對于稀疏的采用Set來存儲而不是數(shù)組,可以節(jié)省存儲空間
AbstractCell實現(xiàn)了Comparator接口住拭,利用row和column來進(jìn)行排序挪略;
cell(int row, int column)方法來獲取指定的cell
@Override
public Cell<V> cell(int row, int column) {
if (exists(row, column)) {
SortedSet<Cell<V>> tail = cells.tailSet(finder(row, column));
if (tail.size() > 0) {
Cell<V> cell = tail.first();
if (cell.getRow() == row && cell.getColumn() == column) {
return cell;
}
}
}
return null;
}
@Override
public boolean exists(int row, int column) {
return row >= 0 && row < rowCount() && column >= 0 && column < columnCount();
}
通過SortedSet來查詢具體的cell;
再來看看DenseGrid
private final int rowCount;
private final int columnCount;
private int size;
private final V[] values;
從代碼里看出废酷,采用的是數(shù)組的存儲方式瘟檩,因為當(dāng)數(shù)據(jù)比較稠密的時候,浪費的空間的少量的澈蟆,這種方式相比較SparseGrid,效率會高卓研,實現(xiàn)比較簡單趴俘;
public static <V> DenseGrid<V> create(int rowCount, int columnCount) {
return new DenseGrid<V>(rowCount, columnCount);
}
private DenseGrid(int rowCount, int columnCount) {
validateCounts(rowCount, columnCount);
this.rowCount = rowCount;
this.columnCount = columnCount;
this.values = (V[]) new Object[rowCount * columnCount];
}
代碼里可以看出來,最開始構(gòu)造方法就已經(jīng)分配了最大容量的數(shù)組奏赘;
@Override
public V get(int row, int column) {
if (exists(row, column)) {
return values[row * columnCount + column];
}
return null;
}
@Override
public Cell<V> cell(int row, int column) {
V value = get(row, column);
return (value != null ? ImmutableCell.of(row, column, value) : null);
}
從get的代碼可以看出來寥闪,就是簡單的數(shù)組下標(biāo)定位,效率非常高磨淌;其他一些需要get的操作都是通過數(shù)組下標(biāo)的方式來做的疲憋,例如public List<V> column(int column)和public List<V> row(int row)等方法;
總結(jié)下梁只,稀疏Grid和非稀疏Grid最大的區(qū)別就是以時間換空間還是以空間換時間的問題缚柳;通過不同的存儲結(jié)構(gòu)來實現(xiàn)埃脏;
總結(jié)
- 從Grid的源碼分析來看,執(zhí)行效率還是不錯的
- Grid的使用場景還是有一些的秋忙,比如一些業(yè)務(wù)場景中的需要多個map來實現(xiàn)的業(yè)務(wù)邏輯彩掐,可以考慮Grid的實現(xiàn)方式,看看哪種實現(xiàn)方式更方便及效率更高灰追;