SetUniqueList使List集合中的元素没有重复值
来源:互联网 发布:rxjava2 遍历数组 编辑:程序博客网 时间:2024/06/04 00:36
List和Set的一个主要区别之一就是List可以存储重复的值,而Set不可以。但是,在某种场合下,要求List不能存重复的值怎么办呢?请看下面的例子:
List<String> list = SetUniqueList.decorate(new ArrayList<String>());list.add("123");list.add("321");list.add("123");for(String str:list){System.out.println(str);}
输出的结果是:123 321。
可以看到,SetUniqueList的decorate方法去掉了重复的值。那么这又是如何做到的呢?其实这个功能的实现依然是用到了Set。
可以先看下SetUniqueList的部分原码:
protected final Set set; public static SetUniqueList decorate(List list) { if (list == null) { throw new IllegalArgumentException("List must not be null"); } if (list.isEmpty()) { return new SetUniqueList(list, new HashSet()); } else { List temp = new ArrayList(list); list.clear(); SetUniqueList sl = new SetUniqueList(list, new HashSet()); sl.addAll(temp); return sl; } }可以看到decorate中作为参数的list是不能为空的。
其带参数的构造方法:
protected SetUniqueList(List list, Set set) { super(list); if (set == null) { throw new IllegalArgumentException("Set must not be null"); } this.set = set; }主要需要看的便是addAll方法:
public boolean addAll(Collection coll) { return addAll(size(), coll); } public boolean addAll(int index, Collection coll) { // gets initial size final int sizeBefore = size(); // adds all elements for (final Iterator it = coll.iterator(); it.hasNext();) { add(it.next()); } // compares sizes to detect if collection changed return sizeBefore != size(); } public boolean add(Object object) { // gets initial size final int sizeBefore = size(); // adds element if unique add(size(), object); // compares sizes to detect if collection changed return (sizeBefore != size()); }public void add(int index, Object object) { // adds element if it is not contained already if (set.contains(object) == false) { super.add(index, object); set.add(object); } }由最后一个add(int index,Object object)方法可以看出,对集合中所包含的元素进行了判断,进而确保集合中的元素无重复。
SetUniqueList继承了AbstractListDecorator,而AbstractListDecorator则实现了List。add(int index,Object object)中的super.add(index,object)其实就是由AbstractListDecorator实现List接口中的add(index,object)方法。
最后顺便贴出SetUniqueList的全部原码,所用的jar包为commons-collections-3.2.1.jar:
/* * $Header$ * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. 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. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowledgement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgement may appear in the software itself, * if and wherever such third-party acknowledgements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR * ITS 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.ListIterator;import java.util.Set;import org.apache.commons.collections.iterators.AbstractIteratorDecorator;import org.apache.commons.collections.iterators.AbstractListIteratorDecorator;import org.apache.commons.collections.list.AbstractListDecorator;import org.apache.commons.collections.set.UnmodifiableSet;/** * Decorates a <code>List</code> to ensure that no duplicates are present * much like a <code>Set</code>. * <p> * The <code>List</code> interface makes certain assumptions/requirements. * This implementation breaks these in certain ways, but this is merely the * result of rejecting duplicates. * Each violation is explained in the method, but it should not affect you. * <p> * The {@link org.apache.commons.collections.set.ListOrderedSet ListOrderedSet} * class provides an alternative approach, by wrapping an existing Set and * retaining insertion order in the iterator. * * @since Commons Collections 3.0 * @version $Revision: 2094 $ $Date: 2004-01-17 03:55:12 +0900 (Sat, 17 Jan 2004) $ * * @author Matthew Hawthorne * @author Stephen Colebourne */public class SetUniqueList extends AbstractListDecorator { /** * Internal Set to maintain uniqueness. */ protected final Set set; /** * Factory method to create a SetList using the supplied list to retain order. * <p> * If the list contains duplicates, these are removed (first indexed one kept). * A <code>HashSet</code> is used for the set behaviour. * * @param list the list to decorate, must not be null * @throws IllegalArgumentException if list is null */ public static SetUniqueList decorate(List list) { if (list == null) { throw new IllegalArgumentException("List must not be null"); } if (list.isEmpty()) { return new SetUniqueList(list, new HashSet()); } else { List temp = new ArrayList(list); list.clear(); SetUniqueList sl = new SetUniqueList(list, new HashSet()); sl.addAll(temp); return sl; } } //----------------------------------------------------------------------- /** * Constructor that wraps (not copies) the List and specifies the set to use. * <p> * The set and list must both be correctly initialised to the same elements. * * @param set the set to decorate, must not be null * @param list the list to decorate, must not be null * @throws IllegalArgumentException if set or list is null */ protected SetUniqueList(List list, Set set) { super(list); if (set == null) { throw new IllegalArgumentException("Set must not be null"); } this.set = set; } //----------------------------------------------------------------------- /** * Gets an unmodifiable view as a Set. * * @return an unmodifiable set view */ public Set asSet() { return UnmodifiableSet.decorate(set); } //----------------------------------------------------------------------- /** * Adds an element to the list if it is not already present. * <p> * <i>(Violation)</i> * The <code>List</code> interface requires that this method returns * <code>true</code> always. However this class may return <code>false</code> * because of the <code>Set</code> behaviour. * * @param object the object to add * @return true if object was added */ public boolean add(Object object) { // gets initial size final int sizeBefore = size(); // adds element if unique add(size(), object); // compares sizes to detect if collection changed return (sizeBefore != size()); } /** * Adds an element to a specific index in the list if it is not already present. * <p> * <i>(Violation)</i> * The <code>List</code> interface makes the assumption that the element is * always inserted. This may not happen with this implementation. * * @param index the index to insert at * @param object the object to add */ public void add(int index, Object object) { // adds element if it is not contained already if (set.contains(object) == false) { super.add(index, object); set.add(object); } } /** * Adds an element to the end of the list if it is not already present. * <p> * <i>(Violation)</i> * The <code>List</code> interface makes the assumption that the element is * always inserted. This may not happen with this implementation. * * @param coll the collection to add */ public boolean addAll(Collection coll) { return addAll(size(), coll); } /** * Adds a collection of objects to the end of the list avoiding duplicates. * <p> * Only elements that are not already in this list will be added, and * duplicates from the specified collection will be ignored. * <p> * <i>(Violation)</i> * The <code>List</code> interface makes the assumption that the elements * are always inserted. This may not happen with this implementation. * * @param index the index to insert at * @param coll the collection to add in iterator order * @return true if this collection changed */ public boolean addAll(int index, Collection coll) { // gets initial size final int sizeBefore = size(); // adds all elements for (final Iterator it = coll.iterator(); it.hasNext();) { add(it.next()); } // compares sizes to detect if collection changed return sizeBefore != size(); } //----------------------------------------------------------------------- /** * Sets the value at the specified index avoiding duplicates. * <p> * The object is set into the specified index. * Afterwards, any previous duplicate is removed * If the object is not already in the list then a normal set occurs. * If it is present, then the old version is removed and re-added at this index * * @param index the index to insert at * @param object the object to set * @return the previous object */ public Object set(int index, Object object) { int pos = indexOf(object); Object result = super.set(index, object); if (pos == -1 || pos == index) { return result; } return remove(pos); } public boolean remove(Object object) { boolean result = super.remove(object); set.remove(object); return result; } public Object remove(int index) { Object result = super.remove(index); set.remove(result); return result; } public boolean removeAll(Collection coll) { boolean result = super.removeAll(coll); set.removeAll(coll); return result; } public boolean retainAll(Collection coll) { boolean result = super.retainAll(coll); set.retainAll(coll); return result; } public void clear() { super.clear(); set.clear(); } public boolean contains(Object object) { return set.contains(object); } public boolean containsAll(Collection coll) { return set.containsAll(coll); } public Iterator iterator() { return new SetListIterator(super.iterator(), set); } public ListIterator listIterator() { return new SetListListIterator(super.listIterator(), set); } public ListIterator listIterator(int index) { return new SetListListIterator(super.listIterator(index), set); } public List subList(int fromIndex, int toIndex) { return new SetUniqueList(super.subList(fromIndex, toIndex), set); } //----------------------------------------------------------------------- /** * Inner class iterator. */ static class SetListIterator extends AbstractIteratorDecorator { protected final Set set; protected Object last = null; protected SetListIterator(Iterator it, Set set) { super(it); this.set = set; } public Object next() { last = super.next(); return last; } public void remove() { super.remove(); set.remove(last); last = null; } } /** * Inner class iterator. */ static class SetListListIterator extends AbstractListIteratorDecorator { protected final Set set; protected Object last = null; protected SetListListIterator(ListIterator it, Set set) { super(it); this.set = set; } public Object next() { last = super.next(); return last; } public Object previous() { last = super.previous(); return last; } public void remove() { super.remove(); set.remove(last); last = null; } public void add(Object object) { if (set.contains(object) == false) { super.add(object); set.add(object); } } public void set(Object object) { throw new UnsupportedOperationException("ListIterator does not support set"); } } }
- SetUniqueList使List集合中的元素没有重复值
- 去除List集合中的重复元素方法
- SetUniqueList生成不重复元素的List的用法和结果
- 自定义判重器,清除List集合中的重复元素。众所周知,List集合元素可重复。
- 循环剔除集合(List)中的重复元素
- 高效除去List集合和数组中的重复元素
- 使用 SetUniqueList 构造不重复的元素列表
- 去除List集合中的重复值
- Set和数学中的集合是同一个概念,就是没有重复元素的集合。
- 将List a 和List b中的元素合并,没有重复的元素,最后返回这个合并的List
- 消除集合中的重复元素
- 删除集合中的重复元素
- 去掉集合中的重复元素
- 去除集合中的重复元素
- Set集合没有重复的元素
- java找出2个集合相同和不同的元素(以及去除List中的重复元素)
- java找出2个集合相同和不同的元素(以及去除List中的重复元素)
- java找出2个集合相同和不同的元素(以及去除List中的重复元素)
- 在VS2008中创建wxWidgets项目向导(一)
- QTP参数类型
- MySQL索引类型一览 让MySQL高效运行起来
- _tmain和main的区别
- jboss for linux安装配置
- SetUniqueList使List集合中的元素没有重复值
- 获取图片大小
- java swing
- android 创建service root权限执行脚本
- 软件工程师如同园丁
- PL/SQL工具优化配置(个性化设置)
- C语言:输入一个数,把他的约数求出。
- plot函数
- IOS深入学习(28)之Property list(属性列表文件)