0

I was wondering why Java and other programming languages implement (seemingly) redundant functions such as:

"foobar".startsWith("bar", 3);
// same as
"foobar".substring(3).startsWith("bar");

// or even indexOf(str, offset), regionMatches(...)

Is there a reason behind this?

  • 4
    Your "same as" isn't correct, the two expressions don't have the same contract. Generally: convenience. – Mat Apr 11 '15 at 7:38
  • 1
    @Mat Could you explain what some of those little differences in contract are? – Ixrec Apr 11 '15 at 15:13
  • 1
    @lxrec: substring throws if the index is out of range. startsWith just returns false. – Mat Apr 11 '15 at 15:15
  • As a related point; 99% of methods are redundant and could each be replaced by several other methods – Richard Tingle Apr 11 '15 at 15:32
6

There are few possible reasons for this sort of thing:

  1. As in JacquesB's answer it may simply be convenience for the library user to call a single method rather than two methods and keep their code more succinct.

  2. Performance may be a consideration. Calling .substring(3) will result in a new string being created, and therefore you are looping over the string twice, it is possible 1 for .startsWith("bar", 3) to be implemented without creating a temporary substring and to just loop through the string once. .startsWith has another tiny optimization point: it can bail out early if the first character does not match, .indexOf will need to keep checking the rest of the string.

  3. Expressing intent: while its fairly obvious what you are doing with either of your two variants it does take the reader a little while to consider the purpose compared to a single method call that will tell you exactly what you are doing.

  4. As Phillipp points out, history can be a factor, adding new methods to an API is fairly easy, changing or removing existing methods is much harder as it will break existing code, so sometimes you may just be seing an artefact of the history of the development of the API 2.

1 I have no idea if this is actually the case here but I'd be surprised if it does.
2 Probably not in this case though.

  • A 4th reason might be historical. They added startsWith first, realized that it doesn't cover all use-cases, and then added substring in a later version which can do the same and more, but they couldn't remove startsWith because it would break backward compatibility. – Philipp Apr 11 '15 at 9:26
  • @Philipp good call, added to answer – jk. Apr 11 '15 at 9:29
  • 3
    an example for a class in the Java standard library which was made redundant by a later addition is Hashtable vs. Collections.synchronizedMap. – Philipp Apr 11 '15 at 9:37
  • @Philipp: Hashtable is still routinely used when thread safety is not required. – Robert Harvey Apr 11 '15 at 15:28
  • @RobertHarvey No, Hashtable is used when thread safety is required. When you don't need thread safety, you use a HashMap. – Philipp Apr 11 '15 at 21:19
5

These are called convenience functions. They are included so users can write shorter and simpler code.

Note that almost every library is "redundant" in the sense that users could write the same code themselves outside of the library. However the point of using libraries is that you save time and code, and you can reuses the knowledge of the library in different projects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.