Morgan Stanley Interview Question for Java Developers


Country: India




Comment hidden because of low score. Click to expand.
3
of 3 vote

You need to use reflection.. This comparator code can be used for any type which implements Comparable interface

package algorithms;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class GenericComparator<T> implements Comparator<T> {

	private String property;

	public GenericComparator(String property) {
		this.property = property;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public int compare(Object o1, Object o2) {
		Comparable o1Comparable = getComparable(o1);
		Comparable o2Comparable = getComparable(o2);
		return o1Comparable.compareTo(o2Comparable);
	}

	@SuppressWarnings("rawtypes")
	private Comparable getComparable(Object o) {
		try {
			Object invoke = o.getClass().getMethod(property, new Class[] {})
					.invoke(o, new Class[] {});
			return ((Comparable)invoke);
		} catch (Exception e) {
			throw new IllegalArgumentException(e.getMessage());
		}
	}

	/**
	 * 
	 * @param args
	 */

	public static void main(String[] args) {

		Student s1 = new Student("david");

		Student s2 = new Student("adam");

		List<Student> list = new ArrayList<Student>();

		list.add(s1);

		list.add(s2);

		System.out.println(list);

		java.util.Collections.sort(list, new GenericComparator<Student>("getName"));
		System.out.println("After sort :" + list);
	}

}

- Pani Dhakshnamurthy September 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice code Pani.. :)
However; your code would not be able to handle basic types like String, Integers etc. So, you could replace getComparable() code as follows:

private Comparable getComparable(Object o) {
		try {
                        if(!(o instanceof Comparable))
                        {
			Object invoke = o.getClass().getMethod(property, new Class[] {})
					.invoke(o, new Class[] {});
			return ((Comparable)invoke);
                        }
                        else
                        {
                            return (Comparable)o;
                        }
		} catch (Exception e) {
			throw new IllegalArgumentException(e.getMessage());
		}
	}

Is there any scope to improvise this code.. Suggestions are welcome.

- Amit Petkar October 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I am confused in line - 
Object invoke = o.getClass().getMethod(property, new Class[] {})
					.invoke(o, new Class[] {});
			return ((Comparable)invoke);

Can you also some insight into the exact Student class

- nini October 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Nini,

If you observe the code "o.getClass().getMethod(property, new Class[] {})", property states the getter method name of the class considered. So, consider Student class as follows:

public class Student
{
	private String name;
	Student(){}
	Student(String name) {this.name = name;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
}

"o.getClass().getMethod(getName, new Class[] {})" would get "getName" method on current object i.e. Student. And ".invoke(o, new Class[] {})" would invoke the same which would return String which can be saved in Object variable and later typecasted as Comparable.

- Amit Petkar October 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Use reflections...
This code is written under following assumptions:
> The objects to be compared should conform to JavaBean Conventions (should have getter methods atleast to all fields to be compared with)
> Currently would be able to handle basic types like String, int and float only (need to add code to handle all comparable types). I am unable to generalise the code to handle all Comparable types. Would appreciate if someone come with the solution for the same.
> I know my code is very crude. Would appreciate if someone would improvise this code that would comply with ethical coding conventions. Also, I believe implementing generics may help. I am unable to come up with that solution though.
> This code is currently comparing all the available field in JavaBean

public class AllComparator implements Comparator<Object> {

    public static boolean isGetter(Method method) {
        if (!method.getName().startsWith("get")) {
            return false;
        }
        if (method.getParameterTypes().length != 0) {
            return false;
        }
        if (void.class.equals(method.getReturnType())) {
            return false;
        }
        return true;
    }

    @Override
    public int compare(Object o1, Object o2) {

        
        if (o1.getClass().toString().equals("class java.lang.String")) {
            return ((String) o1).compareTo((String) o2);
        } else if (o1.getClass().toString().equals("class java.lang.Integer")) {
            return ((Integer) o1).compareTo((Integer) o2);
        } else if (o1.getClass().toString().equals("class java.lang.Float")) {
            return ((Float) o1).compareTo((Float) o2);
        } else {
            Method[] methods = o1.getClass().getMethods();


            int greater = 0;
            int lesser = 0;
            int equals = 0;
            int result = 0;
            String retType = null;

            for (Method method : methods) {
                if (isGetter(method)) {
                    Object obj1 = null, obj2 = null;
                    try {
                        obj1 = method.invoke(o1);
                        obj2 = method.invoke(o2);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    retType = method.getReturnType().toString();

                    if (retType.equals("float")) {
//                    try{
                        float x = Float.parseFloat(obj1.toString());
                        float y = Float.parseFloat(obj2.toString());
                        result = (x > y) ? 1 : (x == y) ? 0 : (-1);
                        if (result > 0) {
                            greater++;
                        }
                        if (result < 0) {
                            lesser++;
                        }
                        if (result == 0) {
                            equals++;
                        }
                    } else if (retType.equals("int")) {
                        int x = Integer.parseInt(obj1.toString());
                        int y = Integer.parseInt(obj2.toString());
                        result = (x > y) ? 1 : (x == y) ? 0 : (-1);
                        if (result > 0) {
                            greater++;
                        }
                        if (result < 0) {
                            lesser++;
                        }
                        if (result == 0) {
                            equals++;
                        }
                    } else if (retType.equals("class java.lang.String")) {
                        String x = obj1.toString();
                        String y = obj2.toString();
                        result = x.compareTo(y);

                        if (result > 0) {
                            greater++;
                        }
                        if (result < 0) {
                            lesser++;
                        }
                        if (result == 0) {
                            equals++;
                        }


                    }



                }
            }


            if (lesser > greater) {
                if (lesser > equals) {
                    return -1;
                } else {
                    return 0;
                }
            } else {
                if (greater > equals) {
                    return 1;
                } else {
                    return 0;
                }
            }

        }
    }
}


class Bean001 {

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public float getC() {
        return c;
    }

    public void setC(float c) {
        this.c = c;
    }
    private int a;
    private String b;
    private float c;
}

public class AllComparatorTester {

public static void main(String[] args) {
        ArrayList al = new ArrayList();
        Bean001 b1 = new Bean001();
        b1.setA(2);
        b1.setB("b");
        b1.setC(3.14f);
        al.add(b1);
//        al.add(2);

        Bean001 b2 = new Bean001();
        b2.setA(1);
        b2.setB("a");
        b2.setC(1.5f);
        al.add(b2);
//        al.add(1);

//        System.out.println("arrayList before sorting.." + al);
//        java.util.Collections.sort(al, new AllComparator());
//        System.out.println("arrayList after sorting.." + al);

        Bean001 x;
        System.out.println("arrayList before sorting..");
        for (Object o : al) {
            x = (Bean001) o;
            System.out.println(x.getA() + " " + x.getB() + " " + x.getC());
        }

        System.out.println("After sorting...");
        java.util.Collections.sort(al, new AllComparator());

        for (Object o : al) {
            x = (Bean001) o;
            System.out.println(x.getA() + " " + x.getB() + " " + x.getC());
        }
        
        

    }
}

- Amit Petkar September 24, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Seems fine to me.

- Anonymous September 24, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

import java.util.Comparator;

public class GComparator<T extends Comparable<T>> implements Comparator<T>
{

@Override
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}
}

- Sameer Shukla October 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Do a bit wise comparison of the input objects. Eg : Comparing number 65 and char 'A'.

- Anonymous September 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

Comparator to compare any type of object you can do so by checking instanceof Integer or String, but suppose two objects are completely different, such as one Integer and one String, in that case it does not make any sense to have such comparator.

- Ghosh September 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Dear Ghosh,
Comparison makes sense if given two objects are mutually comparable. Comparator expects such objects. Read javadoc of Comparator interface.
How are you intending to compare objects and sort a list which comprises String, Integer and some other Javabean say Student.

- Amit Petkar October 01, 2013 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 vote

comparision can always be done...override the method and give normal trivial comparision criteria....

- Dinesh Pant September 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

Compare the memory addresses of the objects!
OR
In Java you can compare the hash codes of the objects.

if(obj1.hashCode() > obj2.hashCode()) {
	return true; //obj1 is greater than obj2
}

- EOF September 23, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You can not depend on the hashcode value. Hashcode can never be used for comparison purpose.

- Ghosh September 24, 2013 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More