Java-删除ArrayList中的重复项
我正在开发一个使用Java-删除ArrayList中的重复项,java,algorithm,arraylist,Java,Algorithm,Arraylist,我正在开发一个使用ArrayList存储字符串的程序。该程序向用户提示菜单,并允许用户选择要执行的操作。这些操作包括向列表中添加字符串、打印条目等。我希望能够创建一个名为removeDuplicates()的方法。此方法将搜索ArrayList,并删除任何重复的值。我想在列表中保留重复值的一个实例。我还希望此方法返回删除的重复项的总数 我一直在尝试使用嵌套循环来实现这一点,但我遇到了麻烦,因为当条目被删除时,ArrayList的索引会被更改,并且事情不会正常工作。我从概念上知道我需要做什么,但在
ArrayList
存储字符串的程序。该程序向用户提示菜单,并允许用户选择要执行的操作。这些操作包括向列表中添加字符串、打印条目等。我希望能够创建一个名为removeDuplicates()
的方法。此方法将搜索ArrayList
,并删除任何重复的值。我想在列表中保留重复值的一个实例。我还希望此方法返回删除的重复项的总数
我一直在尝试使用嵌套循环来实现这一点,但我遇到了麻烦,因为当条目被删除时,ArrayList
的索引会被更改,并且事情不会正常工作。我从概念上知道我需要做什么,但在代码中实现这个想法时遇到了困难
下面是一些伪代码:
从第一个条目开始;
检查列表中的每个后续条目,看它是否与第一个条目匹配;
删除列表中与第一个条目匹配的每个后续条目
检查完所有条目后,转到第二个条目;
检查列表中的每个条目,看它是否与第二个条目匹配;
删除列表中与第二个条目匹配的每个条目
对列表中的条目重复此操作
以下是我目前掌握的代码:
public int removeDuplicates()
{
int duplicates = 0;
for ( int i = 0; i < strings.size(); i++ )
{
for ( int j = 0; j < strings.size(); j++ )
{
if ( i == j )
{
// i & j refer to same entry so do nothing
}
else if ( strings.get( j ).equals( strings.get( i ) ) )
{
strings.remove( j );
duplicates++;
}
}
}
return duplicates;
}
public int-removeDuplicates()
{
重复整数=0;
对于(int i=0;i
更新:看来威尔正在寻找一个家庭作业解决方案,该解决方案涉及开发删除重复项的算法,而不是使用集合的实用解决方案。见他的评论:
谢谢你的建议。这是作业的一部分,我相信老师希望解决方案不包括集合。换句话说,我将提出一个解决方案,该解决方案将在不实现哈希集的情况下搜索和删除重复项。老师建议使用嵌套循环,这正是我试图做的,但在删除某些条目后,我对ArrayList
的索引一直存在一些问题。为什么不使用Set
之类的集合(以及HashSet
之类的实现)这自然可以防止重复?为了澄清我对matt b答案的评论,如果您真的想计算删除的重复数,请使用以下代码:
List<String> list = new ArrayList<String>();
// list gets populated from user input...
Set<String> set = new HashSet<String>(list);
int numDuplicates = list.size() - set.size();
List List=new ArrayList();
//从用户输入中填充列表。。。
Set Set=新哈希集(列表);
int numDuplicates=list.size()-set.size();
使用集合是删除重复项的最佳选择:
如果有阵列列表,则可以删除重复的阵列并保留阵列列表功能:
List<String> strings = new ArrayList<String>();
//populate the array
...
List<String> dedupped = new ArrayList<String>(new HashSet<String>(strings));
int numdups = strings.size() - dedupped.size();
List strings=new ArrayList();
//填充数组
...
List dedupped=new ArrayList(new HashSet(strings));
int numdups=strings.size();
如果无法使用集合,请对数组(Collections.sort())进行排序,并在列表中迭代,检查当前元素是否与上一个元素相等,如果相等,请将其删除。使用集合是最佳选择(如其他人所建议)
如果要相互比较列表中的所有元素,应稍微调整for循环:
for(int i = 0; i < max; i++)
for(int j = i+1; j < max; j++)
for(int i=0;i
这样,您就不会只比较每个元素一次,而不是两次。这是因为与第一个循环相比,第二个循环从下一个元素开始
此外,当在列表中进行迭代时从列表中删除时(即使使用for循环而不是迭代器),请记住减少列表的大小。一种常见的解决方案是保留另一个要删除的项目列表,然后在决定删除哪个项目后,将其从原始列表中删除
我一直在尝试使用嵌套循环来实现这一点,但我遇到了麻烦,因为当条目被删除时,ArrayList的索引会被更改,并且事情不会正常工作
每次删除条目时,为什么不减少计数器
删除条目时,元素也将移动:
ej:
职位:
a[0] = "a";
a[1] = "a";
a[2] = "b";
a[3] = "c";
删除第一个“a”后,索引为:
a[0] = "a";
a[1] = "b";
a[2] = "c";
因此,您应该考虑到这一点,并减少j
(j--
)的值,以避免“跳过”某个值
请参见此屏幕截图:
public Collection removeDuplicates(Collection c) {
// Returns a new collection with duplicates removed from passed collection.
Collection result = new ArrayList();
for(Object o : c) {
if (!result.contains(o)) {
result.add(o);
}
}
return result;
}
或
两个都未经测试。公共ArrayList RemovedDuplicates(ArrayList inArray)
public ArrayList removeDuplicates(ArrayList <String> inArray)
{
ArrayList <String> outArray = new ArrayList();
boolean doAdd = true;
for (int i = 0; i < inArray.size(); i++)
{
String testString = inArray.get(i);
for (int j = 0; j < inArray.size(); j++)
{
if (i == j)
{
break;
}
else if (inArray.get(j).equals(testString))
{
doAdd = false;
break;
}
}
if (doAdd)
{
outArray.add(testString);
}
else
{
doAdd = true;
}
}
return outArray;
}
{
ArrayList outArray=新的ArrayList();
布尔doAdd=真;
对于(int i=0;i
您可以用空字符串*替换副本,从而保持索引的完整性。然后,在完成之后,可以去掉空字符串
*但仅当空字符串在您的实现中无效时。公共条目UniquelementList(包含可能的副本的列表列表){
public <Foo> Entry<Integer,List<Foo>> uniqueElementList(List<Foo> listWithPossibleDuplicates) {
List<Foo> result = new ArrayList<Foo>();//...might want to pre-size here, if you have reliable info about the number of dupes
Set<Foo> found = new HashSet<Foo>(); //...again with the pre-sizing
for (Foo f : listWithPossibleDuplicates) if (found.add(f)) result.add(f);
return entryFactory(listWithPossibleDuplicates.size()-found.size(), result);
}
List result=new ArrayList();/…可能需要预先调整大小
public ArrayList removeDuplicates(ArrayList <String> inArray)
{
ArrayList <String> outArray = new ArrayList();
boolean doAdd = true;
for (int i = 0; i < inArray.size(); i++)
{
String testString = inArray.get(i);
for (int j = 0; j < inArray.size(); j++)
{
if (i == j)
{
break;
}
else if (inArray.get(j).equals(testString))
{
doAdd = false;
break;
}
}
if (doAdd)
{
outArray.add(testString);
}
else
{
doAdd = true;
}
}
return outArray;
}
public <Foo> Entry<Integer,List<Foo>> uniqueElementList(List<Foo> listWithPossibleDuplicates) {
List<Foo> result = new ArrayList<Foo>();//...might want to pre-size here, if you have reliable info about the number of dupes
Set<Foo> found = new HashSet<Foo>(); //...again with the pre-sizing
for (Foo f : listWithPossibleDuplicates) if (found.add(f)) result.add(f);
return entryFactory(listWithPossibleDuplicates.size()-found.size(), result);
}
public <Foo> int removeDuplicates(List<Foo> listWithPossibleDuplicates) {
int original = listWithPossibleDuplicates.size();
Iterator<Foo> iter = listWithPossibleDuplicates.iterator();
Set<Foo> found = new HashSet<Foo>();
while (iter.hasNext()) if (!found.add(iter.next())) iter.remove();
return original - found.size();
}
public class Duplicates {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("one");
list.add("two");
list.add("three");
list.add("three");
list.add("three");
System.out.println("Prior to removal: " +list);
System.out.println("There were " + removeDuplicates(list) + " duplicates.");
System.out.println("After removal: " + list);
}
public static int removeDuplicates(List<String> list) {
int removed = 0;
List<String> temp = new ArrayList<String>();
for(String s : list) {
if(!temp.contains(s)) {
temp.add(s);
} else {
//if the string is already in the list, then ignore it and increment the removed counter
removed++;
}
}
//put the contents of temp back in the main list
list.clear();
list.addAll(temp);
return removed;
}
}
public static int removeDuplicates(ArrayList<String> strings) {
int size = strings.size();
int duplicates = 0;
// not using a method in the check also speeds up the execution
// also i must be less that size-1 so that j doesn't
// throw IndexOutOfBoundsException
for (int i = 0; i < size - 1; i++) {
// start from the next item after strings[i]
// since the ones before are checked
for (int j = i + 1; j < size; j++) {
// no need for if ( i == j ) here
if (!strings.get(j).equals(strings.get(i)))
continue;
duplicates++;
strings.remove(j);
// decrease j because the array got re-indexed
j--;
// decrease the size of the array
size--;
} // for j
} // for i
return duplicates;
}
List<String> list;
List<String> dedupped = new ArrayList<String>(new LinkedHashSet<String>(list));
{"a", "b", "c", "b", "b", "d"}
i j
{"a", "b", "c", "b", "d"}
i j
{"a", "b", "c", "b", "d"}
i j
List<String> lst = new ArrayList<String>();
lst.add("one");
lst.add("one");
lst.add("two");
lst.add("three");
lst.add("three");
lst.add("three");
Set se =new HashSet(lst);
lst.clear();
lst = new ArrayList<String>(se);
for (Object ls : lst){
System.out.println("Resulting output---------" + ls);
}
ArrayList<User> usersList = new ArrayList<User>();
usersList.clear();
User user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("AB");
user.setId("2"); // duplicate
usersList.add(user);
user = new User();
user.setName("C");
user.setId("4");
usersList.add(user);
user = new User();
user.setName("A");
user.setId("1"); // duplicate
usersList.add(user);
user = new User();
user.setName("A");
user.setId("2"); // duplicate
usersList.add(user);
}
class User {
private String name;
private String id;
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param id
* the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the id
*/
public String getId() {
return id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
public static int removeDuplicates(List<String> duplicateList){
List<String> correctedList = new ArrayList<String>();
Set<String> a = new HashSet<String>();
a.addAll(duplicateList);
correctedList.addAll(a);
return (duplicateList.size()-correctedList.size());
}
public List<?> removeDuplicate(List<?> listWithDuplicates) {
int[] intArray = new int[listWithDuplicates.size()];
int dupCount = 1;
int arrayIndex = 0;
int prevListIndex = 0; // to save previous listIndex value from intArray
int listIndex;
for (int i = 0; i < listWithDuplicates.size(); i++) {
for (int j = i + 1; j < listWithDuplicates.size(); j++) {
if (listWithDuplicates.get(j).equals(listWithDuplicates.get(i)))
dupCount++;
if (dupCount == 2) {
intArray[arrayIndex] = j; // Saving duplicate indexes to an array
arrayIndex++;
dupCount = 1;
}
}
}
Arrays.sort(intArray);
for (int k = intArray.length - 1; k >= 0; k--) {
listIndex = intArray[k];
if (listIndex != 0 && prevListIndex != listIndex){
listWithDuplicates.remove(listIndex);
prevListIndex = listIndex;
}
}
return listWithDuplicates;
}
ArrayList al = new ArrayList();
// add elements to al, including duplicates
HashSet hs = new HashSet();
hs.addAll(al);
al.clear();
al.addAll(hs);
for (int i = 0; i < strings.size(); i++) {
for (int j = j + 1; j > strings.size(); j++) {
if(strings.get(i) == strings.get(j)) {
strings.remove(j);
j--;
}`
}
}
return strings;