mjd2
mjd2

Reputation: 318

How do you subtract one array of chars from another in Java?

Let's say I have an array, arrayA = ["a", "b", "c", "d", "e", "f"], and another array, arrayB = ["a", "d", "e"].

I want to subtract arrayB from arrayA to yield the result = ["b", "c", "f"]

This is my setup for each array:

char[] arrayA = new char[7];
for(char c = 'a'; c <= 'f'; ++c) {
    arrayA[c - 'a'] = c;
}
char[] arrayB = new char[]{'a','d','e'};

(Please excuse any improper use of symbols and syntax, I'm a Ruby noob trying to learn Java simply from the Oracle tutorials. Thanks!) edit: a word and quotes

Upvotes: 15

Views: 11823

Answers (6)

Siva
Siva

Reputation: 1940

Convert them to List and call the removeAll method:

Character[] array1 = ArrayUtils.toObject(arrayA);
    Character[] array2 = ArrayUtils.toObject(arrayB);       
    List<Character> list1 = new ArrayList(Arrays.asList(array1));
    List<Character> list2 = new ArrayList(Arrays.asList(array2));
    list1.removeAll(list2);`

Upvotes: 12

luke657
luke657

Reputation: 835

Arrays.asList doesn't work with primitive types like char so you have to iterate through both arrays, change them to the wrapper class Character and add them to sets. Then, you can use removeAll method.

Set<Character> setA = new HashSet<>();
Set<Character> setB = new HashSet<>();
for(int i = 0; i < arrayA.length; i++){
    setA.add(new Character(arrayA[i]));
}
for(int i = 0; i < arrayB.length; i++){
    setA.add(new Character(arrayB[i]));
}
setA.removeAll(setB);
arrayA = new char[setA.size()];
int i = 0;
for(Character c : setA){
    arrayA[i++] = c.charValue();
}

Upvotes: 2

Reigertje
Reigertje

Reputation: 725

Convert your arrays to lists (For example ArrayList) using Arrays.asList(). Generic sets do not take primitive types (so asList won't work on your arrays as they are now) so you can use the object Character instead like this:

Character a[] = {'f', 'x', 'l', 'b', 'y'};
Character b[] = {'x', 'b'};
ArrayList<Character> list1 = new ArrayList<Character>(Arrays.asList(a));
ArrayList<Character> list2 = new ArrayList<Character>(Arrays.asList(b));
list1.removeAll(list2);

Read about generic types here in case you're unfamiliar with them: http://docs.oracle.com/javase/tutorial/java/generics/types.html

In case you do need arrays you can use the toArray() function of ArrayList to recreate an array.

Upvotes: 2

Russell Uhl
Russell Uhl

Reputation: 4531

The short answer is to convert your arrays to "sets", and then use set operations on them. I'm looking for the proper code for that right now, but you can start by checking out this post: Classical set operations for java.util.Collection

Edit: Luke657 brings up a good point. primitive arrays are weird. So below is the updated code:

Assuming you start with a char array (it would of course be better to start with a set, but oh well):

char[] arrayA = new char[] {'a', 'b', 'c', 'd', 'e', 'f'};
char[] arrayB = new char[] {'a', 'd', 'e'};
Character[] objarrayA = ArrayUtils.toObject(arrayA);
Character[] objarrayB = ArrayUtils.toObject(arrayB);
Set<T> setA = new HashSet(Arrays.asList(objarrayA));
Set<T> setB = new HashSet(Arrays.asList(objarrayB));

setA.removeAll(setB);

Then, to get it back to a char array:

Character[] result;
result = setA.toArray(result);
char[] cresult = ArrayUtils.toPrimitive(result);

I believe this will do what you need. The Arrays.asList() operation is O(1), so is efficient and not computationally expensive, so don't worry about that extra conversion.

Upvotes: 24

Ganesh Rengarajan
Ganesh Rengarajan

Reputation: 2006

import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Repeated {

public static void main(String[] args) {
//        Collection listOne = new ArrayList(Arrays.asList("a", "b", "c", "d", "e", "f"));
//        Collection listTwo = new ArrayList(Arrays.asList("a", "d", "e"));
 //
//        listOne.retainAll( listTwo );
//        System.out.println( listOne );

    String[] s1 = {"a", "b", "c", "d", "e", "f"};
    String[] s2 = {"a", "d", "e"};
    List<String> s1List = new ArrayList(Arrays.asList(s1));
    for (String s : s2) {
        if (s1List.contains(s)) {
            s1List.remove(s);
        } else {
            s1List.add(s);
        }
         System.out.println("intersect on " + s1List);
    }
}
}

Upvotes: 2

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70929

I suggest you construct a Set from arrayA and then call removeAll on it using the second array.

If the two arrays are sorted as shown in your question you can solve the problem with a single iteration over the arrays.

Upvotes: 7

Related Questions