回答
Set将自动消除重复,但它是一个集合,而不是一个列表。
我不认为有一个清单,消除标准库中的重复。
Java 6 SE API文档的Annotated Outline of the Collections Framework页面指出“通常允许重复”。
+1指出集合和Lits之间的区别。 – 2013-08-16 11:00:13
如果你想消除重复,使用Set
你想要一个集也许,例如HashSet(),而不是一个List?没有列表将消除重复,按照定义列表允许它们。
就像上面的海报说的那样,没有List with Unique处理。
set不同,列表通常允许重复的元素。更正式地说,列表通常允许元素e1和e2的对,使得e1.equals(e2),并且它们通常允许多个null元素(如果它们完全允许空元素的话)。有人可能希望通过在用户尝试插入时抛出运行时异常来实现禁止重复的列表,这并不是不可想象的,但我们预计这种用法很少见。
稀有...和昂贵。抛出异常很昂贵。 – 2010-09-24 09:42:33
昂贵,真实。但有时不可避免。许多收集方法抛出UnsupportedOperationException,并且客户端代码没有办法找到它们提前做的事情。 RuntimeExceptions是你必须在集合框架中处理的东西。 – 2010-09-24 16:18:51
您可以扩展现有的java.util.ArrayList
并封装其中的java.util.Set
。你应该覆盖所有add(...)
,addAll(...)
和remove
方法与第一次检查,如果一个元素是封装组(的情况下将其添加到列表中的):
public class ListSet<E> extends ArrayList<E> {
private Set<E> set;
public ListSet() {
set = new HashSet<E>();
}
@Override
public boolean add(E element) {
if(set.add(element)) {
super.add(element);
return true;
}
return false;
}
// other add and remove methods
}
编辑
由于@Alnitak提到:不要忘记在删除元素时同步备份HashSet。
我喜欢这个,这就是我会如何做到的。这特别保留了列表的所有语义,同时强制执行无重复约束(尽管以某些内存为代价)。附:不要忘记同步你的支持HashSet每当一个元素被删除... – Alnitak 2010-09-24 10:17:27
我正在考虑做一些非常相似的事情,但我挂在你身上会执行add(index,E)实现。我想如果你在数据中发现了E的重复,那么你在这个位置插入失败。列表
这里是ArrayList中的扩展,它不允许重复:
public class NoDupeList<E> extends ArrayList<E>{
private static final long serialVersionUID = -2682691450003022201L;
public NoDupeList(){
super();
}
public NoDupeList(final Collection<? extends E> c){
super(c instanceof Set<?> ? c : new LinkedHashSet<E>(c));
}
public NoDupeList(final int initialCapacity){
super(initialCapacity);
}
@Override
public boolean add(final E e){
return !this.contains(e) && super.add(e);
};
@Override
public boolean addAll(final Collection<? extends E> c){
final List<E> intermediate = new ArrayList<E>(c);
intermediate.removeAll(this);
return super.addAll(intermediate);
}
@Override
public void add(final int index, final E element){
if(!this.contains(element)){
super.add(index, element);
}
};
@Override
public E set(final int index, final E element){
if(this.contains(element) && !this.get(index).equals(element)){
throw new IllegalArgumentException("This would cause a duplicate");
}
return super.set(index, element);
};
}
我不能处理的唯一事情是set()方法。我的解决方案是抛出一个IllegalArgumentException
如果这会导致重复,但也许应该通常让这个方法抛出一个UnsupportedOperationException
来代替。
总之,这里的测试方法:
@Test
public void testNoDupeList() throws Exception{
final List<String> list =
new NoDupeList<String>(Arrays.asList("abc", "def", "abc"));
assertEquals(list, Arrays.asList("abc", "def"));
list.addAll(Arrays.asList("abc", "def", "ghi"));
assertEquals(list, Arrays.asList("abc", "def", "ghi"));
try{
list.set(2, "abc");
fail("This should have caused an Exception");
} catch(final Exception e){}
};
不要像有人建议,实现自己的名单,做重复检查,如果在添加重复返回false()。
为什么?因为你将打破List接口合同,说:
public boolean add(E e)
[...]
Returns:
true (as specified by Collections.add())
List.add(E E)必须返回true和元素添加到列表中,或抛出异常。列表并不意味着有重复的检查,这是什么集合。
来获取排序并没有重复将它包像这样的实际List
最简单的方法:
List<Integer> unique =
new ArrayList<Integer>(new TreeSet<Integer>(Arrays.asList(1, 1, 2, 2, 3, 3)));
注意,当您添加到这个列表重复将不虽然被淘汰,但也许这对你有用。
当时你可以让自己的班级和@Override
添加方法到你的班级。 “只看我的代码并练习它”
import java.util.ArrayList;
import java.util.List;
class MyList extends ArrayList<Integer> {
private static final long serialVersionUID = 1L;
@Override
public boolean add(Integer element) {
if (!found(element)) {
super.add(element);
}
return false;
}
public boolean found(Integer e) {
return equals(e);
}
public boolean equals(Integer e) {
for (int i = 0; i < super.size(); i++) {
if (super.get(i).equals(e))
return true;
}
return false;
}
}
public class ListRemovingDuplicated {
public static void main(String[] abd) {
List<Integer> obj = new MyList();
obj.add(10);
obj.add(20);
obj.add(10);
obj.add(10);
obj.add(30);
System.out.println(obj);
}
}
- 1. 删除重复在<select><cfoutput><option>
- 2. JSON字典重复自动消除
- 3. 铸造清单<Class>至清单<Interface>
- 4. 铸造清单<SomeClass>至清单<object>
- 5. 构造清单<T>来自枚举<? extends T>
- 6. 删除重复的线<ArrayList中<String>>
- 7. 为什么grok {match => {“message”=>“%{DATA:class}:%{GREEDYDATA:message}”}}重复我的消息?
- 8. SVG清除组<g>
- 9. Android清单:为什么有时“<classname>”而不是“<classname>”?
- 10. 为什么不是我的清单<t>排序工作?
- 11. 为什么我的清单<T>未被序列化?
- 12. 在字典删除重复<INT,列表<PointF>>
- 13. 从ArrayList中删除重复项<HashMap <String,String >>
- 14. 更改Android清单一行<CLASS>原因清除所有
- 15. Java:<init>和<clinit>和有什么不一样?
- 16. <% %>和<%= %>和有什么不一样?
- 17. IEqualityComparer <T>和IEquatable <T>和有什么不一样?
- 18. 有什么样DbSet <T> .RemoveWhere(谓语<T>)
- 19. >> =或<< = C++中的复合赋值有什么用?
- 20. 清除applicationIconBadgeNumber不删除,设置</p> <pre><code>application.applicationIconBadgeNumber = -1 </code></pre> 上<code>applicationDidBecomeActive</code><p>或<code>applicationWillEnterForeground</code>,让我来清除徽章数量,而不从移除通知不工作
- 21. 清除重复的CSS类
- 22. 为什么git会重复添加和删除故事板<classes>部分?
- 23. 什么是“动作<IEnumerable <TwitterStatus>,TwitterResponse>动作”?
- 24. 为什么打电话给我的清单<Point>。清除()抛出一个ArgumentOutOfRangeException?
- 25. 如何使用</p> <pre><code>dbms.lob.createTemporary(v_clob,true) </code></pre> <p>,并尝试使用</p> <pre><code>dbms.lob.freetemporary(v_clob) </code></pre> <p>它不清除CLOB释放清除CLOB的PL SQL
- 26. 如何防止清除我的<input type =“text”>元素的表单重置?
- 27. MySQL自动重复删除
- 28. PHP自动从POST中的数据中删除< and >,为什么?
- 29. 为什么<input>元素ID以嵌套形式重复?
- 30. 为什么我的Windows清单中出现重复条目?
LinkedHashSet是Set接口的一个实现......为什么你推荐这个而不是另一个? – pgras 2010-09-24 07:35:17
@pgras,可能是因为添加元素的顺序保持完整,就像列表一样。 – 2010-09-24 07:37:05
@Wolfgang,@Bart K - 问题是LinkedHashSet不是一个List。它实现了Set API,并且不允许您在位置上获取,更新或插入或删除元素。 – 2010-09-24 07:46:29