0

The program is a text engine that takes in a text file and analyzes it.

public Word findFirst(String text) throws SearchableException, ContentNotLoadedException {
    for(int i = 0;i<words.size();i++) {
        if(text.equals(words.get(i).text)) {
            return words.get(i).text;
        }
    }   
}

This is a method that is supposed to return the first instance of a word that matches the input "text." "words" is the array list that loads all the words. I get an error of "can't convert from string to word" in my return statement and while I understand the error, I can't think of an alternative way to go about doing this?

public class Word {

public final String text;
public final int position;
public final int length;
public final int line;
public final int positionInLine;

 public Word(String text, int position, int length, int line, int positionInLine) {
    this.text = text;
    this.position = position;
    this.length = length;
    this.line = line;
    this.positionInLine = positionInLine;
}

This is the Word class in question.

Edit:I am unable to change the method signature or Word class in any way.

4
  • 1
    public String findFirst...? Commented Dec 3, 2018 at 16:33
  • 2
    why not just "return words.get(i)" instead of "return words.get(i).text"; Commented Dec 3, 2018 at 16:37
  • I swear I tried that out earlier and it didn't work, but now it does..... thank you very much Spara! Commented Dec 3, 2018 at 16:40
  • It's ok bro :D This will happens a lot in programming world! I will make my comment as a answer for you now :) Commented Dec 3, 2018 at 16:41

4 Answers 4

2

If you're on java-8 you can use this to return the first String that matches:

public String findFirst(String text) throws SearchableException {
    return words.stream().filter(i -> i.text.equals(text)).findFirst().get().text;
}

Alternatively, if you want to return the entire object you can use :

public Word findFirst(String text) throws SearchableException {
    return words.stream().filter(i -> i.text.equals(text)).findFirst().get();
}
Sign up to request clarification or add additional context in comments.

5 Comments

the question was not how to rewrite the loops, it was about type conversion
I'm curious if this method is much more efficient. With the authors original code, once a match is found the method returns but your implementation first filters the whole list then returns the first element in the list. If there are 1000 matches I feel like the OP's code will run faster.
That's not how filter works. It is almost the same as OP's code, just that we are using streams. As soon as the filter condition evaluates to true the iteration of the loop will stop and the corresponding instance will be returned due to findFirst(). More info here
The second example doesn't compile because findFirst() returns an Optional instead of a Word.
@DodgyCodeException - Good catch! Missed out the .get()
1

Actually the return type of the method is Word so when your return gives a String it can't goes from String to Word.

  1. To fix this, change return type to String

    public String findFirst(String text) throws SearchableException, ContentNotLoadedException {
        for(int i = 0;i<words.size();i++) {
            if(text.equals(words.get(i).text)) {
                return words.get(i).text;
            }
        }        
    }
    
  2. Or return the whole Word object

    public Word findFirst(String text) throws SearchableException, ContentNotLoadedException {
        for(int i = 0;i<words.size();i++) {
            if(text.equals(words.get(i).text)) {
                return words.get(i);
            }
        }        
    }
    

Tip to simplify the loop

  1. foreach loop

    for (Word word : words) {
        if (text.equals(word.text)) {
            return word.text;
        }
    }
    
  2. Stream

    return words.stream().map(Word::getText).filter(text::equals).findFirst().orElseThrow(()->new SearchableException());
    

1 Comment

The Stream example forces you to think about what happens when the text is not found. What about the loop implementations?
0

Just return words.get(i) instead of return words.get(i).text.

public Word findFirst(String text) throws SearchableException, ContentNotLoadedException {
    for(int i = 0;i<words.size();i++) {
        if(text.equals(words.get(i).text)) {
            return words.get(i);
        }
    }   
return null;
}

1 Comment

What does it do if you don't find the text? This currently doesn't compile because not all paths return a value.
0

Since you cannot change the method signature you have to return an Word instance. So you should not return Word.text but the Word instance directly or a new one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.