Question

I need to write a static method in a class MinTester that computes the "smallest" string from an ArrayList collection using a comparator object:

public static String min(ArrayList<String> list, Comparator<String> comp)

I cannot use the Collections class to compute the minimum.

Here is what I have so far.

public class MinTester
{

static String least;//This is static because it is being used in a static static context


public static String min(ArrayList<String> list, Comparator<String> comp)
{
   int min = 0;


  for( int i = 0; i < list.size(); i++ )
  {
    min = list.get(i).compareTo(list.get(i++));
    if(min < 0)
    {
        least = list.get(i);
    }
    else if(min == 0)
    {
        least = list.get(i);
    }
    else
    {
    least = list.get(i++);
    }
  }
    return least;
}
}

I am using the min value because I read that the compareTo method returns negative, 0, or positive whether the first string is less than, equal to, or greater than the second.

I am not getting any errors here from the method, So I try to test it in Main with this. I get this warning: "Accessing static method min"

   public static void main(String[] args)
{
    // TODO code application logic here

    MinTester s = new MinTester();
    Comparator<String> comp = null;
    ArrayList<String> list = new ArrayList<>();

    list.add("a");
    list.add("ab");
    list.add("abc");
    list.add("abcd");

   String a = s.min(list,comp);//Warning: Accessing static method min

    System.out.println(a);
}

My output from a = "abcd". Can anyone help me figure out why I am getting "abcd" as the 'Min' string in the list? I am thinking that my error is coming from my min() method, but I am not sure where inside it or why.

Was it helpful?

Solution

If you need to find the shortest String in an ArrayList without sorting it, you can simply traverse the list and check the .length attribute of every String, always keeping track of the shortest one.

String shortest = list.get(0);

for(String str : list) {
    if (str.length() < shortest.length()) {
        shortest = str;
    }
}
System.out.println("The shortest string: " + shortest);

EDIT :

You would use Comparator if you wanted to implement custom comparison of two strings. Comparing their length can be done in 1 line, so Comparator is really not necessary. If you absolutely need to use the Comparator, you would replace

if (str.length() < shortest.length())

by

if (comp.compare(str, shortest) < 0))

it's basically the same thing, except that you don't define the comparison by yourself but leave it up to the Comparator to decide, which String of the two is smaller. This way, if you wanted the way how the strings are compared in the future, you wouldn't have to rewrite the method, you would only supply a different Comparator.

OTHER TIPS

Using Streams and Comparator-

Comparator<String> comparator = (str1, str2) -> str1.length() > str2.length() ? 1 : -1;
    String smallest = Arrays.stream(input)
            .sorted(comparator).findFirst().get();

Reference: Find Shortest Length String

you can just use string lengths to compare and use min method of stream:

stringSet.stream().min(Comparator.comparingInt(String::length)).get();

Some pointer, using the Comparator, to get the idea. I'm not going to solve the whole problem, as this is obviously your homework (implement the Comparator for the String lengths, understand what Comparator#compareTo(T, T) returns, read the Comparator API):

public static String min(List<String> list, Comparator<String> comp) {
    String shortest = null;
    for (String current : list) {
        if (shortest == null) { // first iteration
            shortest = current;
            continue;
        }
        int comparisonResult = comp.compare(shortest, current);
        // TODO: your task; update shortest, depending on comparisonResult
    }
    return shortest;
}

Don't want to do all of the work for you, so I will provide a solution in Scala:

object MinTest{

  def main(args: Array[String]){
    val list: util.List[String] = List("a", "ab", "abc", "abcd")
    val m: String = min(list, (s1, s2) => s1.length - s2.length)
    println(m) //output is: a
  }

  def min(list: util.List[String], comp: (String, String) => Int): String = {
    if(list.isEmpty)
      return null
    var min = list(0)
    for(i <- 0 until list.size if comp(list(i), min) < 0)
      min = list(i)
    min
  }
}

Although this is a different language, the logic is still present. It's just your responsibility to convert it to Java.

This is simple guys, cant you just create a hashmap from a list where the number in the hashmap is the length of the string then the value in the hashmap is the string that goes with that value...

Sort by the key, select item zero, then you have it , right?

What I'm saying is put all the strings in a list.. for each loop on that list, while doing so note the string in one column and the length of that string in the other "while you're there" , sort by the length, then pick the first string that goes with that length.

You can get the length of the string element using the length method

e.g. list.get(0).length()

This should return the size of the string

Good Luck

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top