-4

I am trying to solve a exorcise that is supposed to learn me about the Comparable<T> interface. It tells me to find the shortest and longest string in a string array.

I think I am supposed to make my own compareTo() -method because the String.compareTo() method sorts alphabetically. But I can't get what my method should look like.

This is my code so far:

class ComparableTest implements Comparable<String> {

    public static void main(String[] args) {
        String arr[] = {"hei", "hvordan", "gaar", "det", "med", "deg", "a"};
        String tempSto = arr[0]; //long string
        String tempLit = arr[0]; //short string
        for(String e : arr) {
            if(e.compareTo(tempSto) > 0) {
                tempSto = e;
            }
            if(e.compareTo(tempLit) < 0) {
                tempLit = e;
            }
        }
        System.out.println("Longest string is: " + tempSto);
        System.out.println("Shortest string is: " + tempLit);
    }
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
JonLunde
  • 151
  • 1
  • 3
  • 10
  • something like `if (e.length() > tempSto-length()) ...` might help you – vikingsteve Jun 03 '16 at 12:55
  • @Magnarok, you are suppose to use length method for comparing two strings right?? – VSK Jun 03 '16 at 12:56
  • I am supposed to create a compareTo() method which returns an integer based on the length differences between the two compared Strings. – JonLunde Jun 03 '16 at 12:57
  • It's easy to create a if statement and sort it directly, but the excercise stated that I was supposed to create a compareTo()-method for the Comparable interface. Was just wondering if there is a obvious easy way that i missed. :) – JonLunde Jun 03 '16 at 12:59
  • @Magnarok, I guess you are in wrong direction. Please understand what is the usage of compareTo method before you use it. – VSK Jun 03 '16 at 13:00
  • @VSK as I understand it, it is to compare two objects. When you implement comparable you create your own compareTo()-method to your needs. Where I am stuck is; how am I supposed to create a compareTo()-method with one parameter and compare two strings? – JonLunde Jun 03 '16 at 13:03
  • One liner: `Collections.sort(Arrays.asList(arr), (s1, s2)-> s1.length() - s2.length());` – Subhrajyoti Majumder Jun 03 '16 at 13:04
  • @Magnarok, I guess, its better to implement comparator interface and use compare method for comparing two strings length. – VSK Jun 03 '16 at 13:10
  • @VSK Yea, I figured out that I probably overthinked this and is supposed to create my own compareTo()-method with no connection to comparable. – JonLunde Jun 03 '16 at 13:14

6 Answers6

3

As you mentioned, you should implement your own Comparator, based on the String's length, not its alphabetical contents. E.g.:

public class StringLengthComparator extends Comparator<String> {
    @Override
    public int compare (String s1, String s2) {
        return Integer.compare(s1.length(), s2.length();
    }
}

Once you've done that, you can use it to find the shortest string in the array, or just reuse Collections#min(Collection, Comparator) to do the heavy lifting for you:

String shortest = 
    Collections.min(Arrays.asList(arr), new StringLengthComparator());
luckyguy73
  • 1,850
  • 2
  • 11
  • 21
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • So it is alright to take in two parameters? Thought the compareTo()-method only had one parameter. – JonLunde Jun 03 '16 at 13:00
  • actually, why are you extending the `Comparator` rather than implementing `Comparable`? – dingalapadum Jun 03 '16 at 13:01
  • @Magnarok `Comparable#compareTo` has one argument, as you are comparing it to the object calling the method. Since you can't rewrite `String`'s code, you need an external `Comparator`. – Mureinik Jun 03 '16 at 13:01
  • 1
    @dingalapadum As answered to Magnarok's - `String`s have their own ordering as they implement `Comparable`. If you want to implement a different ordering, you need a different `Comparator`. – Mureinik Jun 03 '16 at 13:02
  • Oh, I understood this differently: OP should probably implement `Comparable` in his `ComparableTest`-class. Thereby he should probably compare `ComparableTest`-Objects which might be just a wrapper for a String... but it might well be that I got this wrong... – dingalapadum Jun 03 '16 at 13:04
  • I think I have overthinked this. I am probably supposed to create my own compareTo() with two parameters, was to fixed on the comparable signature. – JonLunde Jun 03 '16 at 13:05
  • Ok, after reading @Magnarok last comment I guess you are correct. – dingalapadum Jun 03 '16 at 13:07
  • @Magnarok there is no such thing as a `compareTo` with two parameters, only a `compare` method with two parameters, from the `Comparator` interface, not the `Comparable` interface. – Louis Wasserman Jun 03 '16 at 16:57
0

If your class implements the Comparable interface, i guess you have to override the compareTo method, and compare the length of the two String compared.

Omegaspard
  • 1,828
  • 2
  • 24
  • 52
  • an interface does not provide an implementation. You don't have to "override" compareTo. You have to implement it. – dingalapadum Jun 03 '16 at 13:06
  • You can have default method in an interface that may need an override and most of the IDE puts the @Override annotation when you have to implements an unimplemented method, but yes ok – Omegaspard Jun 03 '16 at 13:09
  • you are right - since java 8 there are default methods for interfaces... didn't know about that.... – dingalapadum Jun 03 '16 at 13:18
0

You can use a comparable to sort a list according to your own needs. This means in your case, that the highest and lowest number of characters in a string is relevant for the comparing. So, you subtract those value from each other in the comparing function. If you have for example house and dog, you have the two values 5 and 3. By subtracting the values from each other, you get the difference on how close those values are. So, just return the difference of the length of the two parameters in your ordering function. The first and last element in the list will then be the largest and smallest word (depending on which value you subtract from which).

ssc-hrep3
  • 15,024
  • 7
  • 48
  • 87
0

In Java 8:

import java.util.Arrays;

public class Example {

    public static void main(String[] args) {

        String arr[] = {"hei", "hvordan", "gaar", "det", "med", "deg", "a"};

        String minLengthStr = Arrays.stream(arr)
                                    .min((str1, str2) -> Integer.compare(str1.length(), str2.length()))
                                    .get();

        String maxLengthStr = Arrays.stream(arr)
                                    .max((str1, str2) -> Integer.compare(str1.length(), str2.length()))
                                    .get();

        System.out.println("Longest string is: " + maxLengthStr);
        System.out.println("Shortest string is: " + minLengthStr);
    }
}

Output:

Longest string is: hvordan
Shortest string is: a

Explanation:

The min method in the Stream class takes a Comparator as a parameter. As Comparator is a functional interface we can use a lambda expression as a short hand for implementing it.

So instead of writing:

Comparator<String> lengthComparator = new Comparator<String>() {
    @Override
    public int compare(String str1, String str2) {
        return Integer.compare(str1.length(), str2.length());
    }
};

You can write:

Comparator<String> lengthComparator = (str1, str2) -> Integer.compare(str1.length(), str2.length());

You can use this without streams too:

public class Example {

    public static void main(String[] args) {

        String arr[] = {"hei", "hvordan", "gaar", "det", "med", "deg", "a"};

        String minLengthStr = arr[0], maxLengthStr = arr[0];

        Comparator<String> lengthComparator = (str1, str2) -> Integer.compare(str1.length(), str2.length());

        for(String str : arr) {
            if(lengthComparator.compare(str, minLengthStr) == -1) {
                minLengthStr = str;
            } else if(lengthComparator.compare(str, maxLengthStr) == 1) {
                maxLengthStr = str;
            }
        }

        System.out.println("Longest string is: " + maxLengthStr);
        System.out.println("Shortest string is: " + minLengthStr);
    }
}
explv
  • 2,709
  • 10
  • 17
0

I hope,this will help

public class Test implements Comparator<String>{

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //String arr[] = {"hei", "hvordan", "gaar", "det", "med", "deg", "a"};

        Set<String> set = new TreeSet<String>(new Test());
        set.add("hei");
        set.add("hvordan");
        set.add("gaar");
        set.add("med");
        set.add("deg");
        set.add("a");

        System.out.println(set);
    }

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        if(o1.length()>o2.length())
            return 1;
        else if(o1.length()<o2.length())
            return -1;
        else
            return 0;

    }
VSK
  • 250
  • 4
  • 13
0

If you want to play with String, Comparable and compareTo here is an example.

ideone.com

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {
    String arr[] = {"hei", "hvordan", "gaar", "det", "med", "deg", "a"};

    /**
     * Use composition.
     */
    class MyComparableString implements Comparable<MyComparableString> {
        String myString;

        MyComparableString(String s) {
            myString = s;
        }

        @Override
        public int compareTo(MyComparableString other) {
            // Compare the lengths of the strings in this and other.
            Integer l1 = myString.length();
            Integer l2 = other.myString.length();
            return l1.compareTo(l2);
        }

        // String representation.
        public String toString() {
            return myString;
        }
    }

    void go() {
        // Convert the String array into a List (Collection) of MyComparableString.
        List<MyComparableString> l = new ArrayList<>();
        for (String s: arr) {
            l.add(new MyComparableString(s));
        }
        // Print longest and shortest.
        System.out.println("Shortest: " + Collections.min(l));
        System.out.println("Longest: " + Collections.max(l));
    }

    public static void main(String[] args) {
        new Test().go();
    }
}
totoro
  • 2,469
  • 2
  • 19
  • 23