I am trying to return 2 values from a Java method but I get these errors. Here is my code:
// Method code
public static int something(){
int number1 = 1;
int number2 = 2;
return number1, number2;
}
// Main method code
public static void main(String[] args) {
something();
System.out.println(number1 + number2);
}
Error:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement
at assignment.Main.something(Main.java:86)
at assignment.Main.main(Main.java:53)
Java Result: 1
Instead of returning an array that contains the two values or using a generic Pair class, consider creating a class that represents the result that you want to return, and return an instance of that class. Give the class a meaningful name. The benefits of this approach over using an array are type safety and it will make your program much easier to understand.
Note: A generic Pair class, as proposed in some of the other answers here, also gives you type safety, but doesn't convey what the result represents.
Example (which doesn't use really meaningful names):
final class MyResult {
private final int first;
private final int second;
public MyResult(int first, int second) {
this.first = first;
this.second = second;
}
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
}
// ...
public static MyResult something() {
int number1 = 1;
int number2 = 2;
return new MyResult(number1, number2);
}
public static void main(String[] args) {
MyResult result = something();
System.out.println(result.getFirst() + result.getSecond());
}
Java does not support multi-value returns. Return an array of values.
// Function code
public static int[] something(){
int number1 = 1;
int number2 = 2;
return new int[] {number1, number2};
}
// Main class code
public static void main(String[] args) {
int result[] = something();
System.out.println(result[0] + result[1]);
}
You could implement a generic Pair if you are sure that you just need to return two values:
public class Pair<U, V> {
/**
* The first element of this <code>Pair</code>
*/
private U first;
/**
* The second element of this <code>Pair</code>
*/
private V second;
/**
* Constructs a new <code>Pair</code> with the given values.
*
* #param first the first element
* #param second the second element
*/
public Pair(U first, V second) {
this.first = first;
this.second = second;
}
//getter for first and second
and then have the method return that Pair:
public Pair<Object, Object> getSomePair();
You can only return one value in Java, so the neatest way is like this:
return new Pair<Integer>(number1, number2);
Here's an updated version of your code:
public class Scratch
{
// Function code
public static Pair<Integer> something() {
int number1 = 1;
int number2 = 2;
return new Pair<Integer>(number1, number2);
}
// Main class code
public static void main(String[] args) {
Pair<Integer> pair = something();
System.out.println(pair.first() + pair.second());
}
}
class Pair<T> {
private final T m_first;
private final T m_second;
public Pair(T first, T second) {
m_first = first;
m_second = second;
}
public T first() {
return m_first;
}
public T second() {
return m_second;
}
}
Here is the really simple and short solution with SimpleEntry:
AbstractMap.Entry<String, Float> myTwoCents=new AbstractMap.SimpleEntry<>("maximum possible performance reached" , 99.9f);
String question=myTwoCents.getKey();
Float answer=myTwoCents.getValue();
Only uses Java built in functions and it comes with the type safty benefit.
Use a Pair/Tuple type object , you don't even need to create one if u depend on Apache commons-lang. Just use the Pair class.
you have to use collections to return more then one return values
in your case you write your code as
public static List something(){
List<Integer> list = new ArrayList<Integer>();
int number1 = 1;
int number2 = 2;
list.add(number1);
list.add(number2);
return list;
}
// Main class code
public static void main(String[] args) {
something();
List<Integer> numList = something();
}
public class Mulretun
{
public String name;;
public String location;
public String[] getExample()
{
String ar[] = new String[2];
ar[0]="siva";
ar[1]="dallas";
return ar; //returning two values at once
}
public static void main(String[] args)
{
Mulretun m=new Mulretun();
String ar[] =m.getExample();
int i;
for(i=0;i<ar.length;i++)
System.out.println("return values are: " + ar[i]);
}
}
o/p:
return values are: siva
return values are: dallas
I'm curious as to why nobody has come up with the more elegant callback solution. So instead of using a return type you use a handler passed into the method as an argument. The example below has the two contrasting approaches. I know which of the two is more elegant to me. :-)
public class DiceExample {
public interface Pair<T1, T2> {
T1 getLeft();
T2 getRight();
}
private Pair<Integer, Integer> rollDiceWithReturnType() {
double dice1 = (Math.random() * 6);
double dice2 = (Math.random() * 6);
return new Pair<Integer, Integer>() {
#Override
public Integer getLeft() {
return (int) Math.ceil(dice1);
}
#Override
public Integer getRight() {
return (int) Math.ceil(dice2);
}
};
}
#FunctionalInterface
public interface ResultHandler {
void handleDice(int ceil, int ceil2);
}
private void rollDiceWithResultHandler(ResultHandler resultHandler) {
double dice1 = (Math.random() * 6);
double dice2 = (Math.random() * 6);
resultHandler.handleDice((int) Math.ceil(dice1), (int) Math.ceil(dice2));
}
public static void main(String[] args) {
DiceExample object = new DiceExample();
Pair<Integer, Integer> result = object.rollDiceWithReturnType();
System.out.println("Dice 1: " + result.getLeft());
System.out.println("Dice 2: " + result.getRight());
object.rollDiceWithResultHandler((dice1, dice2) -> {
System.out.println("Dice 1: " + dice1);
System.out.println("Dice 2: " + dice2);
});
}
}
You don't need to create your own class to return two different values. Just use a HashMap like this:
private HashMap<Toy, GameLevel> getToyAndLevelOfSpatial(Spatial spatial)
{
Toy toyWithSpatial = firstValue;
GameLevel levelToyFound = secondValue;
HashMap<Toy,GameLevel> hm=new HashMap<>();
hm.put(toyWithSpatial, levelToyFound);
return hm;
}
private void findStuff()
{
HashMap<Toy, GameLevel> hm = getToyAndLevelOfSpatial(spatial);
Toy firstValue = hm.keySet().iterator().next();
GameLevel secondValue = hm.get(firstValue);
}
You even have the benefit of type safety.
Return an Array Of Objects
private static Object[] f ()
{
double x =1.0;
int y= 2 ;
return new Object[]{Double.valueOf(x),Integer.valueOf(y)};
}
In my opinion the best is to create a new class which constructor is the function you need, e.g.:
public class pairReturn{
//name your parameters:
public int sth1;
public double sth2;
public pairReturn(int param){
//place the code of your function, e.g.:
sth1=param*5;
sth2=param*10;
}
}
Then simply use the constructor as you would use the function:
pairReturn pR = new pairReturn(15);
and you can use pR.sth1, pR.sth2 as "2 results of the function"
You also can send in mutable objects as parameters, if you use methods to modify them then they will be modified when you return from the function. It won't work on stuff like Float, since it is immutable.
public class HelloWorld{
public static void main(String []args){
HelloWorld world = new HelloWorld();
world.run();
}
private class Dog
{
private String name;
public void setName(String s)
{
name = s;
}
public String getName() { return name;}
public Dog(String name)
{
setName(name);
}
}
public void run()
{
Dog newDog = new Dog("John");
nameThatDog(newDog);
System.out.println(newDog.getName());
}
public void nameThatDog(Dog dog)
{
dog.setName("Rutger");
}
}
The result is:
Rutger
You can create a record (available since Java 14) to return the values with type safety, naming and brevity.
public record MyResult(int number1, int number2) {
}
public static MyResult something() {
int number1 = 1;
int number2 = 2;
return new MyResult(number1, number2);
}
public static void main(String[] args) {
MyResult result = something();
System.out.println(result.number1() + result.number2());
}
First, it would be better if Java had tuples for returning multiple values.
Second, code the simplest possible Pair class, or use an array.
But, if you do need to return a pair, consider what concept it represents (starting with its field names, then class name) - and whether it plays a larger role than you thought, and if it would help your overall design to have an explicit abstraction for it. Maybe it's a code hint...
Please Note: I'm not dogmatically saying it will help, but just to look, to see if it does... or if it does not.
I am trying to trim a string to the first occurrence of a specific word in a single string of comma separated words. E.g.:
deleteLastOccurrence("foo,bar,dog,cat,dog,bird","dog")
should return
"foo,bar,dog"
I have the following, and it doesn't seem to be working correctly:
public String deleteLastOccurrence(String original, String target){
String[] arr = original.split(",");
arr = Arrays.copyOfRange(arr, Arrays.asList(arr).indexOf(target), original.length()-1);
path = StringUtils.join(pathArray,",");
}
Any suggestions on a simpler method? Thanks in advance...
Use regex replace:
public static String deleteLastOccurrence(String original, String target){
return original.replaceAll("(,)?\\b" + target + "\\b.*", "$1" + target);
}
This code also works when the target is the first or last word in the original (hence the regex syntax \b which means "word boundary")
Also, rename your method to deleteAfterFirstOccurrence(), because your current name is misleading: The "last occurrence" is irrelevant to what you want.
Here's a little test:
public static void main(String[] args) {
// Test for target in middle:
System.out.println(deleteLastOccurrence("foo,bar,dog,cat,dog,bird,dog", "dog"));
// Test for target at start:
System.out.println(deleteLastOccurrence("dog,bar,dog,cat,dog,bird,dog", "dog"));
// Test for target at end:
System.out.println(deleteLastOccurrence("foo,bar,cat,bird,dog", "dog"));
}
Output:
foo,bar,dog
dog
foo,bar,cat,bird,dog
UPDATE: Looked closer at question and realized that I wrote the name of the method, not the result OP wanted. So, it just gets rid of the last occurrence, doesn't trim after it. Oh well! :)
Depending on your style, you might not think this is simpler. But, it was a fun problem. I think this code is a bit more clear.
public class ReplaceLast {
public String deleteLastOccurrence(String fromThis, String word){
int wordLength = word.length();
if(fromThis.startsWith(word + ",")){
return fromThis.substring(wordLength + 1);
}
if(fromThis.endsWith("," + word)){
return fromThis.substring(0, fromThis.length() - wordLength - 1);
}
int index = fromThis.lastIndexOf("," + word + ",");
if(index == -1){
return fromThis;
}
return fromThis.substring(0, index) + fromThis.substring(index+word.length() + 1);
}
#Test
public void testNotThere() {
String actual = deleteLastOccurrence("foo,bar,dog,cat,dog,bird","moose");
assertEquals("foo,bar,dog,cat,dog,bird", actual);
}
#Test
public void testMiddle() {
String actual = deleteLastOccurrence("foo,bar,dog,cat,dog,bird","dog");
assertEquals("foo,bar,dog,cat,bird", actual);
}
#Test
public void testFirst() {
String actual = deleteLastOccurrence("foo,bar,dog,cat,dog,bird","foo");
assertEquals("bar,dog,cat,dog,bird", actual);
}
#Test
public void testLast() {
String actual = deleteLastOccurrence("foo,bar,dog,cat,dog,bird","bird");
assertEquals("foo,bar,dog,cat,dog", actual);
}
#Test
public void testSubword() {
String actual = deleteLastOccurrence("foo,bar,dog,cat,dog,bird","bir");
assertEquals("foo,bar,dog,cat,dog,bird", actual);
}
}
I tried to solve the problem of trimming a string on the first occurrence of a specific word and I didn't care about the original name of the method (deleteLastOccurrence) that is IMO misleading.
The trick to match only single word and not subwords for me is to add two commas before and after the sentence and then check the word with commas.
i.e. ",dog," will be checked against ",foo,bar,dog,cat,dog,bird," for presence.
package gicappa;
public class So {
public static String trimSentenceOnFirstOccurrenceOf(String sentence, String word) {
if (word.isEmpty()) return sentence;
if (!addCommasAround(sentence).contains(addCommasAround(word))) return sentence;
return trimAddedCommasOf(substringOfSentenceUntilEndOfWord(addCommasAround(sentence), addCommasAround(word)));
}
public static String substringOfSentenceUntilEndOfWord(String string, String word) {
return string.substring(0, string.indexOf(word) + word.length());
}
public static String trimAddedCommasOf(String string) {return string.substring(1,string.length()-1);}
public static String addCommasAround(String s) {return "," + s + ","; }
}
and if you'd fancy some testing I used for TDD, here we go:
package gicappa;
import org.junit.Test;
import static gicappa.So.trimSentenceOnFirstOccurrenceOf;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
public class SoTest {
#Test
public void it_returns_the_same_sentence_for_empty_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", ""), is(equalTo("foo,bar,dog,cat,dog,bird")));
}
#Test
public void it_returns_the_same_sentence_for_not_contained_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", "s"), is(equalTo("foo,bar,dog,cat,dog,bird")));
}
#Test
public void it_returns_the_first_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", "foo"), is(equalTo("foo")));
}
#Test
public void it_returns_the_same_sentence_if_is_matched_the_last_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", "bird"), is(equalTo("foo,bar,dog,cat,dog,bird")));
}
#Test
public void it_trims_after_the_end_of_the_first_matched_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", "dog"), is(equalTo("foo,bar,dog")));
}
#Test
public void it_does_not_trim_for_a_subword_of_a_contained_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("foo,bar,dog,cat,dog,bird", "do"), is(equalTo("foo,bar,dog,cat,dog,bird")));
}
#Test
public void it_does_not_trim_for_a_subword_of_an_already_contained_word() {
assertThat(trimSentenceOnFirstOccurrenceOf("dog,foozzo,foo,cat,dog,bird", "foo"), is(equalTo("dog,foozzo,foo")));
}
}
A wordy refactoring for a more OO class could also be:
package gicappa;
public class Sentence {
private String s;
public Sentence(String sentence) {
this.s = sentence;
}
public String trimOnFirstOccurrenceOf(String word) {
if (word.isEmpty() || csvSentenceContainsWord(word)) return s;
return substringSentenceToEndOf(word);
}
private String substringSentenceToEndOf(String word) {
return addCommasTo(s).substring(1, addCommasTo(s).indexOf(addCommasTo(word)) + addCommasTo(word).length()-1);
}
private boolean csvSentenceContainsWord(String word) {
return !addCommasTo(s).contains(addCommasTo(word));
}
public static String addCommasTo(String s) {return "," + s + ",";}
}
with usage like:
new Sentence("dog,foozzo,foo,cat,dog,bird").trimOnFirstOccurrenceOf("foo"), is(equalTo("dog,foozzo,foo"))
How about this:
public String deleteLastOccurrence(String original, String target){
return original.replace("(^|,)" + target + "(,|$)", "");
}
Here's a try at a non-regex version:
public String trimTo(String in, String matchNoCommas) {
if (in.startsWith(matchNoCommas + ",")) // special check here...
return matchNoCommas;
int idx = in.indexOf("," + matchNoCommas+ ",");
if (idx < 0)
return in;
return in.substring(0, idx + matchNoCommas.length()+1);
}
Provides the same results as the regex version by #Bohemian. Your call as to which is more understandable.
Maybe I'm wrong, but wouldn't this do?
public trimCommaSeparatedListToIncludeFirstOccurrenceOfWord(String listOfWords, String wordToMatch) {
int startOfFirstOccurrenceOfWordToMatch = listOfWords.indexOf(wordToMatch);
int endOfFirstOccurrenceOfWordToMatch = startOfFirstOccurrenceOfWordToMatch + wordToMatch.length() - 1;
return listOfWords.substring(0, endOfFirstOccurrenceOfWordToMatch);
}
Now this might not be what the OP wanted, but I think it's what the OP asked for. Example: f("doggy,cat,bird", "dog") would return "dog".
For full-word matching, I'd regex the sucker as others have suggested.
gonzoc0ding, after reading all responses, IMHO your way of do it is the simpler and cleaner, except that should be corrected this way:
public String deleteLastOccurrence(String original, String target){
String[] arr = original.split(",");
arr = Arrays.copyOfRange(arr,0, Arrays.asList(arr).indexOf(target));
path = StringUtils.join(arr,",");
}
But maybe I have not understand your requirements...