Unisex Bathroom problem with semaphore
Your code has a bug.  I can reproduce it fairly consistently by changing your run method to:

@Override
public void run() {
    try {
        for(int i=0;i&lt;100;i++) {
            uniSexBathroom.occupy(person);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


Notice, that I've increased the number of times that each thread tries to occupy the bathroom.  Starting/Stopping threads is a fairly slow process so in order to encourage more contention I used a loop so more time is spent trying to get into the bathroom.  It results in a null pointer in the acquireGenderSemaphore method on this line:

if (!personSex.type.equals(currentGender.type)) {


It's happening because currentGender is null.  We can be confident about this, because personSex is the same for every call for a given thread.  How is it null?  Well, because this isn't safe:

if (currentSize.get() == 0) {
    currentGenderSemaphore.acquire();
    currentGender = personSex;
}


The problem is that context switches can happen at any time, so just because currentSize wasn't 0 for the if evaluation, it doesn't mean that it's still zero during the execution of the if block.

So:

Thread2 is currently in the bathroom (Size 1)

Thread1 comes in to acquire the lock, checks the value of current size and finds it's 1, skip the if block

if (currentSize.get() == 0) {  // Size still 1


Thread2, which is currently using the bathroom leaves:

noOfEntriesSemaphore.release();
currentSize.decrementAndGet(); // Size becomes 0


Thread2, then checks if they were the last one out, which they were:

if (currentSize.get() == 0) {
    currentGenderSemaphore.release();
    currentGender = null;  // Gender becomes null
}


Thread1 then proceeds, assuming there is still somebody in the bathroom:

if (!personSex.type.equals(currentGender.type)) {


But since currentGender has been set to null by Thread 2 when it left.... Bang.