Stack Exchange
How to optimize duplicate code where only the class changes?
I have a basic question in Java which has plagued me for quite some time. Consider the following example:
ArrayAdapter<CarDetailsAdapter.OwnerType> ownerTypeArrayAdapter = new ArrayAdapter<CarDetailsAdapter.OwnerType>(
                CarDetailsActivity.this, android.R.layout.simple_spinner_dropdown_item, CarDetailsAdapter.OwnerType.values());
        ownerSpinner.setAdapter(ownerTypeArrayAdapter);
        ownerSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                owner_result = Integer.toString(((CarDetailsAdapter.OwnerType) ownerSpinner.getSelectedItem()).value);
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        ArrayAdapter<CarDetailsAdapter.DriverType> driver_type = new ArrayAdapter<CarDetailsAdapter.DriverType> (
        CarDetailsActivity.this, android.R.layout.simple_spinner_dropdown_item, CarDetailsAdapter.DriverType.values());
        driverSpinner.setAdapter(driver_type);
        driverSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                driver_result = Integer.toString(((CarDetailsAdapter.DriverType) driverSpinner.getSelectedItem()).value);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

The above code can be explained as follows:
1 - Create an ArrayAdapter (Iterator) of type OwnerType/DriverType which are two different enums
2 - Attach the adapter to a spinner 
3 - When a value is selected in spinner (based on onItemSelected listener) update the result based on the variable
Although the code is specific to Android I think the fundamentals can be extended to Java as well.
Both code snippets are virtually identical except for the Input Class (Enum) ie CarDetailsAdapter.OwnerType & CarDetailsAdapter.DriverType.
Is there some way this functionality can be converted into a function so that I don't have to redundantly repeat the same lines of code? I have tried reflection for hours hoping it would solve the problem but I think I am missing something.
Thanks

Do those two classes implement a common interface?

Sounds like a case for generics.

Not currently but I can make them

Something like this could work:
interface Callback<T> {
    void complete(T result);
}

public <T> void spinner(int spinnerId, Class<? extends Enum> enumClass, final Callback<T> callback) {

    final Spinner spinner = (Spinner) getActivity().findViewById(spinnerId);
    ArrayAdapter<Enum> arrayAdapter = new ArrayAdapter<Enum>(
            getActivity(), android.R.layout.simple_spinner_dropdown_item, enumClass.getEnumConstants());
    spinner.setAdapter(arrayAdapter);
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            T result = (T) spinner.getSelectedItem();
            callback.complete(result);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });
}

// ....

spinner(R.id.ownerSpinner, CarDetailsAdapter.OwnerType.class, new Callback<CarDetailsAdapter.OwnerType>() {
        @Override
        public void complete(CarDetailsAdapter.OwnerType result) {
            owner_result = result;
        }     
    });

You may want to return the spinner as well or adjust in other ways.

Is there some way I can also abstract the listener section, since that part is also the same between the two code snippets?

I updated the code, I think that should give you what you're looking for.

Yes this is similar to what I also ended up implementing. Thanks
