@NonNull
    private static <K, T> PagedList<T> create(@NonNull DataSource<K, T> dataSource,
            @NonNull Executor notifyExecutor,
            @NonNull Executor fetchExecutor,
            @Nullable BoundaryCallback<T> boundaryCallback,
            @NonNull Config config,
            @Nullable K key) {
        if (dataSource.isContiguous() || !config.enablePlaceholders) {
            int lastLoad = ContiguousPagedList.LAST_LOAD_UNSPECIFIED;
            if (!dataSource.isContiguous()) {
                //noinspection unchecked
                dataSource = (DataSource<K, T>) ((PositionalDataSource<T>) dataSource)
                        .wrapAsContiguousWithoutPlaceholders();
                if (key != null) {
                    lastLoad = (Integer) key;
                }
            }
            ContiguousDataSource<K, T> contigDataSource = (ContiguousDataSource<K, T>) dataSource;
            return new ContiguousPagedList<>(contigDataSource,
                    notifyExecutor,
                    fetchExecutor,
                    boundaryCallback,
                    config,
                    key,
                    lastLoad);
        } else {
            return new TiledPagedList<>((PositionalDataSource<T>) dataSource,
                    notifyExecutor,
                    fetchExecutor,
                    boundaryCallback,
                    config,
                    (key != null) ? (Integer) key : 0);
        }
    }
@ NonNull private static < K , T > PagedList < T > create ( @ NonNull DataSource < K , T > dataSource , @ NonNull Executor notifyExecutor , @ NonNull Executor fetchExecutor , @ Nullable BoundaryCallback < T > boundaryCallback , @ NonNull Config config , @ Nullable K key ) { if ( dataSource . isContiguous ( ) || ! config . enablePlaceholders ) { int lastLoad = ContiguousPagedList . LAST_LOAD_UNSPECIFIED ; if ( ! dataSource . isContiguous ( ) ) { dataSource = ( DataSource < K , T > ) ( ( PositionalDataSource < T > ) dataSource ) . wrapAsContiguousWithoutPlaceholders ( ) ; if ( key != null ) { lastLoad = ( Integer ) key ; } } ContiguousDataSource < K , T > contigDataSource = ( ContiguousDataSource < K , T > ) dataSource ; return new ContiguousPagedList < > ( contigDataSource , notifyExecutor , fetchExecutor , boundaryCallback , config , key , lastLoad ) ; } else { return new TiledPagedList < > ( ( PositionalDataSource < T > ) dataSource , notifyExecutor , fetchExecutor , boundaryCallback , config , ( key != null ) ? ( Integer ) key : 0 ) ; } }
Create a PagedList which loads data from the provided data source on a background thread,
posting updates to the main thread.


@param dataSource DataSource providing data to the PagedList
@param notifyExecutor Thread that will use and consume data from the PagedList.
Generally, this is the UI/main thread.
@param fetchExecutor Data loading will be done via this executor -
should be a background thread.
@param boundaryCallback Optional boundary callback to attach to the list.
@param config PagedList Config, which defines how the PagedList will load data.
@param <K> Key type that indicates to the DataSource what data to load.
@param <T> Type of items to be held and loaded by the PagedList.

@return Newly created PagedList, which will page in data from the DataSource as needed.