Java/Collections Data Structure/Paging

Материал из Java эксперт
Версия от 21:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Implementation of PaginatedList backed by an ArrayList

   <source lang="java">

/*

*  Copyright 2004 Clinton Begin
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /**

* Implementation of PaginatedList backed by an ArrayList
* 
*/

public class PaginatedArrayList implements PaginatedList {

 private static final ArrayList EMPTY_LIST = new ArrayList(0);
 private List list;
 private List page;
 private int pageSize;
 private int index;
 /**
  * @param pageSize
  */
 public PaginatedArrayList(int pageSize) {
   this.pageSize = pageSize;
   this.index = 0;
   this.list = new ArrayList();
   repaginate();
 }
 /**
  * Constructor to set the initial size and the page size
  * 
  * @param initialCapacity -
  *          the initial size
  * @param pageSize -
  *          the page size
  */
 public PaginatedArrayList(int initialCapacity, int pageSize) {
   this.pageSize = pageSize;
   this.index = 0;
   this.list = new ArrayList(initialCapacity);
   repaginate();
 }
 /**
  * Constructor to create an instance using an existing collection
  * 
  * @param c -
  *          the collection to build the instance with
  * @param pageSize -
  *          the page size
  */
 public PaginatedArrayList(Collection c, int pageSize) {
   this.pageSize = pageSize;
   this.index = 0;
   this.list = new ArrayList(c);
   repaginate();
 }
 private void repaginate() {
   if (list.isEmpty()) {
     page = EMPTY_LIST;
   } else {
     int start = index * pageSize;
     int end = start + pageSize - 1;
     if (end >= list.size()) {
       end = list.size() - 1;
     }
     if (start >= list.size()) {
       index = 0;
       repaginate();
     } else if (start < 0) {
       index = list.size() / pageSize;
       if (list.size() % pageSize == 0) {
         index--;
       }
       repaginate();
     } else {
       page = list.subList(start, end + 1);
     }
   }
 }
 /* List accessors (uses page) */
 public int size() {
   return page.size();
 }
 public boolean isEmpty() {
   return page.isEmpty();
 }
 public boolean contains(Object o) {
   return page.contains(o);
 }
 public Iterator iterator() {
   return page.iterator();
 }
 public Object[] toArray() {
   return page.toArray();
 }
 public Object[] toArray(Object a[]) {
   return page.toArray(a);
 }
 public boolean containsAll(Collection c) {
   return page.containsAll(c);
 }
 public Object get(int index) {
   return page.get(index);
 }
 public int indexOf(Object o) {
   return page.indexOf(o);
 }
 public int lastIndexOf(Object o) {
   return page.lastIndexOf(o);
 }
 public ListIterator listIterator() {
   return page.listIterator();
 }
 public ListIterator listIterator(int index) {
   return page.listIterator(index);
 }
 public List subList(int fromIndex, int toIndex) {
   return page.subList(fromIndex, toIndex);
 }
 /* List mutators (uses master list) */
 public boolean add(Object o) {
   boolean b = list.add(o);
   repaginate();
   return b;
 }
 public boolean remove(Object o) {
   boolean b = list.remove(o);
   repaginate();
   return b;
 }
 public boolean addAll(Collection c) {
   boolean b = list.addAll(c);
   repaginate();
   return b;
 }
 public boolean addAll(int index, Collection c) {
   boolean b = list.addAll(index, c);
   repaginate();
   return b;
 }
 public boolean removeAll(Collection c) {
   boolean b = list.removeAll(c);
   repaginate();
   return b;
 }
 public boolean retainAll(Collection c) {
   boolean b = list.retainAll(c);
   repaginate();
   return b;
 }
 public void clear() {
   list.clear();
   repaginate();
 }
 public Object set(int index, Object element) {
   Object o = list.set(index, element);
   repaginate();
   return o;
 }
 public void add(int index, Object element) {
   list.add(index, element);
   repaginate();
 }
 public Object remove(int index) {
   Object o = list.remove(index);
   repaginate();
   return o;
 }
 /* Paginated List methods */
 public int getPageSize() {
   return pageSize;
 }
 public boolean isFirstPage() {
   return index == 0;
 }
 public boolean isMiddlePage() {
   return !(isFirstPage() || isLastPage());
 }
 public boolean isLastPage() {
   return list.size() - ((index + 1) * pageSize) < 1;
 }
 public boolean isNextPageAvailable() {
   return !isLastPage();
 }
 public boolean isPreviousPageAvailable() {
   return !isFirstPage();
 }
 public boolean nextPage() {
   if (isNextPageAvailable()) {
     index++;
     repaginate();
     return true;
   } else {
     return false;
   }
 }
 public boolean previousPage() {
   if (isPreviousPageAvailable()) {
     index--;
     repaginate();
     return true;
   } else {
     return false;
   }
 }
 public void gotoPage(int pageNumber) {
   index = pageNumber;
   repaginate();
 }
 public int getPageIndex() {
   return index;
 }

} /*

* Copyright 2004 Clinton Begin
* 
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

/**

* Interface for lists that support paging
* 
*/

interface PaginatedList extends List {

 /**
  * Returns the maximum number of items per page
  * 
  * @return The maximum number of items per page.
  */
 public int getPageSize();
 /**
  * Is the current page the first page?
  * 
  * @return True if the current page is the first page or if only a single page
  *         exists.
  */
 public boolean isFirstPage();
 /**
  * Is the current page a middle page (ie not first or last)?
  * 
  * @return True if the current page is not the first or last page, and more
  *         than one page exists (always returns false if only a single page
  *         exists).
  */
 public boolean isMiddlePage();
 /**
  * Is the current page the last page?
  * 
  * @return True if the current page is the last page or if only a single page
  *         exists.
  */
 public boolean isLastPage();
 /**
  * Is a page available after the current page?
  * 
  * @return True if the next page is available
  */
 public boolean isNextPageAvailable();
 /**
  * Is a page available before the current page?
  * 
  * @return True if the previous page is available
  */
 public boolean isPreviousPageAvailable();
 /**
  * Moves to the next page after the current page. If the current page is the
  * last page, wrap to the first page.
  * 
  * @return True if the page changed
  */
 public boolean nextPage();
 /**
  * Moves to the page before the current page. If the current page is the first
  * page, wrap to the last page.
  * 
  * @return True if the page changed
  */
 public boolean previousPage();
 /**
  * Moves to a specified page. If the specified page is beyond the last page,
  * wrap to the first page. If the specified page is before the first page,
  * wrap to the last page.
  * 
  * @param pageNumber
  *          The page to go to
  */
 public void gotoPage(int pageNumber);
 /**
  * Returns the current page index, which is a zero based integer. All
  * paginated list implementations should know what index they are on, even if
  * they don"t know the ultimate boundaries (min/max).
  * 
  * @return The current page
  */
 public int getPageIndex();

}

 </source>
   
  
 
  



Paging over a collection

   <source lang="java">
   

/*

* Copyright (c) 2003-2006, Simon Brown
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*   - Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*
*   - Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in
*     the documentation and/or other materials provided with the
*     distribution.
*
*   - Neither the name of Pebble nor the names of its contributors may
*     be used to endorse or promote products derived from this software
*     without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

import java.util.List; /**

* Helper class that implements paging over a collection.
*
* @author    Simon Brown
*/

public class Pageable<T> {

 /** the default page size */
 public static final int DEFAULT_PAGE_SIZE = 10;
 private static final int PAGE_WINDOW = 10;
 /** the list over which this class is paging */
 private List<T> list;
 /** the page size */
 private int pageSize = DEFAULT_PAGE_SIZE;
 /** the current page */
 private int page;
 /** the starting index */
 private int startingIndex;
 /** the ending index */
 private int endingIndex;
 /** the maximum number of pages */
 private int maxPages;
 /**
  * Creates a new instance with the specified list.
  *
  * @param list    a List
  */
 public Pageable(List<T> list) {
   this.list = list;
   this.page = 1;
   this.maxPages = 1;
   calculatePages();
 }
 private void calculatePages() {
   if (pageSize > 0) {
     // calculate how many pages there are
     if (list.size() % pageSize == 0) {
       maxPages = list.size() / pageSize;
     } else {
       maxPages = (list.size() / pageSize) + 1;
     }
   }
 }
 /**
  * Gets the list that this instance is paging over.
  *
  * @return  a List
  */
 public List<T> getList() {
   return this.list;
 }
 /**
  * Gets the subset of the list for the current page.
  *
  * @return  a List
  */
 public List<T> getListForPage() {
   return list.subList(startingIndex, endingIndex);
 }
 /**
  * Gets the page size.
  *
  * @return  the page size as an int
  */
 public int getPageSize() {
   return this.pageSize;
 }
 /**
  * Sets the page size.
  *
  * @param pageSize   the page size as an int
  */
 public void setPageSize(int pageSize) {
   this.pageSize = pageSize;
   calculatePages();
 }
 /**
  * Gets the page.
  *
  * @return  the page as an int
  */
 public int getPage() {
   return this.page;
 }
 /**
  * Sets the page size.
  *
  * @param p    the page as an int
  */
 public void setPage(int p) {
   if (p >= maxPages) {
     this.page = maxPages;
   } else if (p <= 1) {
     this.page = 1;
   } else {
     this.page = p;
   }
   // now work out where the sub-list should start and end
   startingIndex = pageSize * (page-1);
   if (startingIndex < 0) {
     startingIndex = 0;
   }
   endingIndex = startingIndex + pageSize;
   if (endingIndex > list.size()) {
     endingIndex = list.size();
   }
 }
 /**
  * Gets the maximum number of pages.
  *
  * @return  the maximum number of pages as an int
  */
 public int getMaxPages() {
   return this.maxPages;
 }
 /**
  * Determines whether there is a previous page and gets the page number.
  *
  * @return  the previous page number, or zero
  */
 public int getPreviousPage() {
   if (page > 1) {
     return page-1;
   } else {
     return 0;
   }
 }
 /**
  * Determines whether there is a next page and gets the page number.
  *
  * @return  the next page number, or 0
  */
 public int getNextPage() {
   if (page < maxPages) {
     return page+1;
   } else {
     return 0;
   }
 }
 /**
  * Gets the minimum page in the window.
  *
  * @return  the page number
  */
 public int getMinPageRange() {
   if (getPage() > PAGE_WINDOW) {
     return getPage() - PAGE_WINDOW;
   } else {
     return 1;
   }
 }
 /**
  * Gets the maximum page in the window.
  *
  * @return  the page number
  */
 public int getMaxPageRange() {
   if (getPage() < (getMaxPages() - PAGE_WINDOW)) {
     return getPage() + PAGE_WINDOW;
   } else {
     return getMaxPages();
   }
 }

}



 </source>