我有一个ArrayList<String>,我想从它中删除重复的字符串。我该怎么做呢?
当前回答
可能有点夸张,但我喜欢这种孤立的问题。:)
这段代码使用了一个临时Set(用于唯一性检查),但直接删除原始列表中的元素。由于在ArrayList中删除元素会导致大量的数组复制,因此可以避免使用remove(int)-方法。
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
说到这里,下面是LinkedList的一个版本(好多了!)
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
使用标记界面为List提供统一的解决方案:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
编辑:我猜泛型的东西并没有真正增加任何价值在这里。哦。:)
其他回答
如果您希望列表自动忽略重复项并保持其顺序,则可以创建HashList(HashMap嵌入式列表)。
public static class HashList<T> extends ArrayList<T>{
private HashMap <T,T> hashMap;
public HashList(){
hashMap=new HashMap<>();
}
@Override
public boolean add(T t){
if(hashMap.get(t)==null){
hashMap.put(t,t);
return super.add(t);
}else return false;
}
@Override
public boolean addAll(Collection<? extends T> c){
HashList<T> addup=(HashList<T>)c;
for(int i=0;i<addup.size();i++){
add(addup.get(i));
}return true;
}
}
使用的例子:
HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);
如果您使用的模型类型为List< T>/ArrayList< T>。希望,它能帮到你。
下面是我的代码,没有使用任何其他数据结构,如set或hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}
可能有点夸张,但我喜欢这种孤立的问题。:)
这段代码使用了一个临时Set(用于唯一性检查),但直接删除原始列表中的元素。由于在ArrayList中删除元素会导致大量的数组复制,因此可以避免使用remove(int)-方法。
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
说到这里,下面是LinkedList的一个版本(好多了!)
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
使用标记界面为List提供统一的解决方案:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
编辑:我猜泛型的东西并没有真正增加任何价值在这里。哦。:)
如果你不想重复,使用Set而不是List。要将List转换为Set,可以使用以下代码:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
如果确实有必要,可以使用相同的结构将Set转换回List。
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
推荐文章
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何读一个文本文件到一个列表或数组与Python
- Linq选择列表中存在的对象(A,B,C)
- 如何找到Java堆大小和内存使用(Linux)?
- 返回大列表中每n项的python方式
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- Python:查找列表中的元素
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?