Reputation: 121
Java beginner, so please bear with possibly silly questions.
I have a list of Strings which contains multiple duplicates and I want to detect and remove these duplicates. I know there's an easy way to do this with HashSet, and I've actually got it to work like that. But originally I was trying to do it in another way, also quite simple, in which there's something wrong and I don't understand what it is.
Given an array of strings with one duplicate, say {"A", "B", "C", "A"}, I can detect and replace the duplicate ("A" here). But if I have an array of strings with multiple duplicates, say {"A", "B", "C", "A", "E", "A"}, something goes wrong in the loop inside my method "replaceDuplicate()".
I need help to understand where the problem is in the following code:
public class TryTask_B2_Vector {
public static void main(String[] args) {
// Create array of strings for all the 'Gars':
String[] garList = new String[] {"A", "B", "C", "A", "E", "A"};
// Display the original "ArrayList" of 'Gars':
System.out.println("Original list of Gars: " + garList);
System.out.println();
bruteForce(garList);
System.out.println(bruteForce(garList));
System.out.println();
replaceDuplicate(garList);
System.out.println();
bruteForce(garList);
System.out.println(bruteForce(garList));
System.out.println();
System.out.println("New list of Gars: " + garList);
}
public static boolean bruteForce(String[] input){
for(int i=0; i < input.length; i++){
for(int j=0; j < input.length; j++){
if(input[i].equals(input[j]) && i != j){
return true;
}
}
}
return false;
}
public static String[] replaceDuplicate(String[] input){
for(int i=0; i < input.length; i++){
for(int j=0; j < input.length; j++){
if(input[i].equals(input[j]) && i != j){
input[j] = input[j].replace(input[j], "null");
System.out.println(input[j]);
}
}
}
return input;
}
}
Upvotes: 0
Views: 3799
Reputation: 662
by using the 2 ways we can remove the duplicate elements from list object in java..i.e 1. by using for each 2. by using iterator ex. using for each
ArrayList<String> wordDulicate = new ArrayList<String>();
ArrayList<String> tempList= new ArrayList<String>();
wordDulicate.add("Tom");
wordDulicate.add("Jones");
wordDulicate.add("Sam");
for (String dupWord : wordDulicate) {
if (!tempList.contains(dupWord)) {
tempList.add(dupWord);
}
}
2. by using iterator
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext())
{
YourClass o = (YourClass) iterador.next();
if(!l2.contains(o)) l2.add(o);
}
hit like if you like the answer...
Upvotes: 0
Reputation: 8499
The program works fine and it replaces the duplicates with the String "null". So the output of { "A", "B", "C", "A", "E", "A" }
would be [A, B, C, null, E, null]
. There are two confusing bits in the print out statements. One the second bruteForce()
method still returns true stating there are still duplicates. Actually this duplicate value is the string "null". Second the multiple null print outs. In the replaceDuplicate()
you are first setting value to "null" and then do the printing which will always print null.
Another point. The inner loop for j
need not start from 0. We just need to look ahaead for duplicates. So it could start from (i+1) for (int j = i+1; j < input.length; j++)
. Saves some additional looping and you could avoid i != j
check.
Modify your program like
import java.util.Arrays;
public class TryTask_B2_Vector {
public static void main(String[] args) {
// Create array of strings for all the 'Gars':
String[] garList = new String[] { "A", "B", "C", "A", "E", "A" };
// Display the original "ArrayList" of 'Gars':
System.out.println("Original list of Gars: " + Arrays.toString(garList));
System.out.println();
bruteForce(garList);
System.out.println("Has duplicates : " + bruteForce(garList));
System.out.println();
replaceDuplicate(garList);
System.out.println();
bruteForce(garList);
System.out.println("Has duplicates : " + bruteForce(garList));
System.out.println();
System.out.println("New list of Gars: " + Arrays.toString(garList));
}
public static boolean bruteForce(String[] input) {
for (int i = 0; i < input.length; i++) {
for (int j = i+1; j < input.length; j++) {
if (!"null".equals(input[i]) && input[i].equals(input[j])) {
return true;
}
}
}
return false;
}
public static String[] replaceDuplicate(String[] input) {
for (int i = 0; i < input.length; i++) {
for (int j = i+1; j < input.length; j++) {
if (!"null".equals(input[i]) && input[i].equals(input[j])) {
System.out.println("Duplicate found : " + input[j]);
input[j] = input[j].replace(input[j], "null");
}
}
}
return input;
}
}
Upvotes: 2
Reputation: 2874
Probably need some modifications but:
@Test
public void test(){
String[] garList = new String[] {"A", "B", "C", "A", "E", "A"};
//remove duplicates
String[] noDup = new String[garList.length];
for(int i =0; i<garList.length; i++){
if(!contains(noDup, garList[i])){
noDup[i] = garList[i];
}
}
System.out.println(Arrays.toString(noDup));
// move nulls to the end
String[] tailNull = new String[garList.length];
int j = 0;
for (int i = 0; i < noDup.length; i++) {
if(noDup[i]!=null){
tailNull[j] = noDup[i];
j++;
}
}
System.out.println(Arrays.toString(tailNull) + "/" + j);
// copy range of not null elements
String[] noNull = new String[j];
System.arraycopy(tailNull, 0, noNull, 0, j);
System.out.println(Arrays.toString(noNull));
}
boolean contains(String[] array, String o){
for (int i = 0; i < array.length; i++) {
if(o.equals(array[i]))
return true;
}
return false;
}
remove duplicates and duplicated nulls.
Upvotes: 1
Reputation: 2248
The problem is in your bruteforce
method. You are expecting it to return false
after you have removed all the duplicates, but this is not the case. Your replace method
is working ok and putting the String null
where the duplicates A appeared. It is putting in more than one String null
(one for each extra 'A' ) and because of this your bruteforce method still sees duplicates and still returns true
. Just add
if(!input[i].equals("null"))
To your bruteforce method and it should be fine
Upvotes: 1