I used following method to add my data to ArrayList.
ArrayList<Word> wordList = new ArrayList<Word>();
Word word = new Word();
word.set_id(id);
word.setWord(word);
word.setDefinition(definition);
wordList.add(word);
After the add some data, I want find the position of the any id which I want find in ArrayList.
Already I have tried following method to get position by id. But it isn't work.
int position = wordList.indexOf(id);
and
int position = wordList.lastIndexOf(id);
Both codes always generated "position = -1" as a result. How can I do that?
Edited
This is the code of the Word.java class. How can I implement equal method?
public class Word {
private String _id, word, definition, favourite, usage;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getDefinition() {
return definition;
}
public void setDefinition(String definition) {
this.definition = definition;
}
public String getFavourite() {
return favourite;
}
public void setFavourite(String favourite) {
this.favourite = favourite;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}
indexOf is trying to compare Word objects. Your list doesn't contain ids as the elements, so you get -1.
You need to use a loop and search the list.
int id = 3;
int position = -1;
for (int i = 0; i < wordlist.size(); i++) {
if (wordlist.get(i).getId() == id) {
position = i;
// break; // uncomment to get the first instance
}
}
Note: this will search the whole list to find the last index of that id. So if there are duplicates and you only want the first one (or stop the loop as soon as you find what you want) add a break in the if statement.
Implement equals method in the "Word" object. Inside equals method you can apply equals only to id field.
Create a new Word object with that id and pass that object in indexOf. Don't pass the id in the indexOf. Pass the new of existing Word object with the required id.
Then indexOf will return the valid index of this word object.
For searching the object in a list. you need to override equals method in your Word class. otherwise you will get -1. because indexOf internally used equals method to search the element in list.
The class inside your list should implement hascode() and equals() in order to have indexOf() that works.
Related
I'm supposed to complete a class named "substitute" that can change elements of a LinkedList between them. I've been trying to figure this on my own but I'm kinda new to programming and I wasn't able to find the answer, I would be grateful if someone could help me. Thanks in advance.
I'm given this code which I cannot change, only write between the brackets:
import java.util.Iterator;
import java.util.LinkedList;
public class Device implements Iterable<String>{
private static int numDevices=0; //device counter... static atribute
private String name;
private int id;
protected LinkedList<String> words;
public boolean substitute(String word1, String word2) {
//You can't use ListIterator<>
//You must use indexOf()...
//incomplete code that I'm not allowed to change ahead:
int position = this.words.indexOf(word1.toLowerCase());
return true;
}
I'm also supposed to pass this JUnit5 test:
assertTrue(d1.substitute("amigo", "perla")); //returns true because the word amigo exists --> returns true
assertFalse(d1.substitute("amigo", "perla")); //the word amigo does not exist --> returns false
assertTrue(d1.substitute("estamos", "estas"));
assertTrue(d1.substitute("que", null)); //remove the word que
assertTrue(d1.substitute("tal", null)); //remove the word tal
The LinkedList Class in Java has methods that can help you complete this problem. With the index found in the position, you can call the remove() or set() function to help complete your code.
public boolean substitute(String word1, String word2) {
int position = this.words.indexOf(word1.toLowerCase());
if(position == -1) {
return false; // index of -1 means the word wasn't found in the list, return false
}
if(word2 == null) { // remove item if word2 is null as indicated by tests
words.remove(position);
} else {
words.set(position, word2); // set word2 at the position word1 was found at
}
return true;
}
I am getting a error for incompatible string and int. How do I fix the error?
Here is what I am trying to get. getSongByTitle(title:String):int a method that takes the song title as input and returns as output the position of the song in the list. If not found, the method returns -1.
public int getSongByTitle(String title){
if (title == this.songList.length){
return this.songList[title];
}
else if (title != this.songList.length){
return -1;
}
}
You're probably better off with the songList being a list rather than array, this will mean you can easily add and remove songs from it and will give you the utility function indexOf which you can use to implement getSongByTitle.
private final List<String> songList = new ArrayList<String>();
public int getSongByTitle(String title) {
return songList.indexOf(title);
}
I guess you need something like this function:
public int getSongByTitle(String title) {
for(int i=0; i<this.songList.length; i++) {
if (title.equals(this.songList[i])) // or what ever you want to compare
return i;
}
// if you do not found any thing
return -1;
}
My program asks a question multiple times by an array but I need to get the answer from that String turned into the integer 1. Know I know how to convert any old String into it's integer counterpart if the string is a bunch of number i.e numbers = 12345 using Integer.parseInt(numbers). What happens if I have a character in the string but I want it to take an integer value of 1? I've got it set out this like this so far
String[] elements = {"Vote A for Football", "Vote B for Basketball"};
String question
int football = 0; // not sure if these should be strings or integers
int basketball = 0;
int tally;
for (String element : elements)
{
System.out.println(element);
}
question = JOptionPane.showInputDialog("What is your favourite sport?");
tally = Integer.parseInt(question);
The last line is the part that gets me because I want them to vote by either entering A or B but I also need the console to print how many times they have voted for that sport (it's an array exercise so the question will appear multiple times).
Welcome to SO. I'm not sure what you're asking, but it would be best to keep the storage of values as integers, and keep strings more of an interface to the user. This way you can readily calculate values without any conversion. Only when you present it to the user should you need to convert.
Having said that, if you are parsing a string (like "A" or "B"), you can store their response as a string, and then compare it against a list of known values using if and equals:
if ("A".equals(question)){
football++;
} else if ("B".equals(question)) {
basketball++;
} else {
// do nothing, process error, ask question again.
}
Also remember to close your statement when initializing your variable:
String question;
or
String question = "";
But as #Jean-François Savard mentions, the variable should make sense as well, so this would be clearer:
String userResponse = "";
Another approach to use Enums
public enum Game {
A {
#Override
public String getGame() {
return "Football";
}
#Override
public int getNumber() {
// TODO Auto-generated method stub
return 1;
}
},
B {
#Override
public String getGame() {
return "Basketball";
}
#Override
public int getNumber() {
// TODO Auto-generated method stub
return 2;
}
};
public abstract String getGame();
public abstract int getNumber();
}
I couldn't remove object.How can I remove a object from an arraylist?
my code
List<kisi> x=new ArrayList<kisi>();
x.add(new kisi("1","betül"));
x.add(new kisi("2","hatice"));
x.add(new kisi("3","selma"));
kisi k=new kisi("2","hatice");
for (int i = 0; i < x.size(); i++) {
if (x.get(i).id==k.id) {
Object obj = x.remove(i);
break;
}
}
my constructor
public class kisi {
public static String id="0";
public static String ad="0";
public kisi(String id,String ad) {
// TODO Auto-generated constructor stub
this.id=id;
this.ad=ad;
}
Solution
Remove the statics from your member variables in your kisi class.
But also note
new kisi("1","betül")
So your id is a String.
When you go through the list comparing ids you do so with ==.
== in java is a same comparison, not an equal comparison. This is unlike the behavior for strings in C# say.
So what you should do is this:
for (int i = 0; i < x.size(); i++) {
if (x.get(i).id.equals(k.id)) { //change here
Object obj = x.remove(i);
break;
}
}
In this simple example this is not causing the problem because the two "2" strings are the same. Which leads me to conclude there's something funny going on your kisi constructor. This is the one I used and the code worked as was:
public class kisi {
public String id;
public kisi(String id, String string2) {
this.id = id;
}
}
A constructor like this will break the code without the .equals call:
public kisi(String id, String string2) {
this.id = id + string2;
}
To remove an Element safely from a list while traversing it you need to do it with an iterator. Otherwise you might get strange results!
Calling remove in foreach loop in Java
In java the only method for removing an item from a list while traversing it is via Iterator.
How can I implement binary search to find a string with a particular prefix in generic array (which in this case will be a string[]). I tried compareTo but that wouldn't help because i have to use a string prefix. eg String prefix "Bi" bill, bilards ...etc..
Implement the following method to return all strings in an alphabetically sorted array that start with a given prefix. For instance, given a prefix “bi”, the returned strings are ”Bill Clinton”, ”Bill Gates”, and ”Bill Joy”. Note that all string comparisons should be case INSENSITIVE. The strings in the returned list must be in the order in which they appear in the array. Your implementation must be based on binary search, and must run in worst case O(log n+k) time, where n is the length of the array, and k is the number of matching strings. Assume that the array has no duplicate entries. If there are no matches, you may either return null, or an empty array list.
You may use the following String methods (in addition to any others you may recall):
boolean startsWith(String s)
int compareTo(String s)
int compareToIgnoreCase(String s)
String toLowerCase(String s)
String toUpperCase(String s)
(As for ArrayList, you only need to use the add method to add an item to the end of the array list.)
You may write helper methods (with full implementation) as necessary. You may not call any method that you have not implemented yourself
public static <T extends Comparable<T>> ArrayList prefixMatch(T[] list, String prefix) {
ArrayList<T> result = new ArrayList<T>();
int lo = 0;
int hi = list.length - 1;
while(lo <= hi) {
int mid = (hi + lo) / 2;
list[mid].startsWith(prefix) ? 0 : list[mid].compareTo((T) prefix));
}
return null;
}
You can use default binary search with custom comparator as your base, and then work our range by your self. I think the right algorithm would be:
Perform binary search on given array. Use comparator which checks only for prefix.
As result you'll get index of string which starts with your prefix
Walk to the left to find first string which matches prefix, remember position.
Walk to the right to find first string which matches prefix, remember position.
Copy elements from range start to range end from original array. That will be your desired array of all elements with prefix match condition.
Below is implementation in java. It works in happy case scenario but will crash if(I left those checks out to make code look simple):
No strings with given prefix exist in original array
There are string with length less then prefix length
Also if you need binary search implementation you could check source of Arrays.binarySearch
public class PrefixMatch {
public static void main(String[] args) {
final String[] prefixMathces = prefixMatch(new String[] { "Abc", "Abcd", "Qwerty", "Pre1", "Pre2", "Pre3", "Xyz", "Zzz" }, "pre");
for (int i = 0; i < prefixMathces.length; i++)
System.out.println(prefixMathces[i]);
}
public static String[] prefixMatch(final String[] array, final String prefix) {
final Comparator<String> PREFIX_COMPARATOR = new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o1.substring(0, prefix.length()).compareToIgnoreCase(o2);
}
};
final int randomIndex = Arrays.binarySearch(array, prefix, PREFIX_COMPARATOR);
int rangeStarts = randomIndex, rangeEnds = randomIndex;
while (rangeStarts > -1 && array[rangeStarts].toLowerCase().startsWith(prefix.toLowerCase()))
rangeStarts--;
while (rangeEnds < array.length && array[rangeEnds].toLowerCase().startsWith(prefix.toLowerCase()))
rangeEnds++;
return Arrays.copyOfRange(array, rangeStarts + 1, rangeEnds);
}
}
I assume that you currently have something like this? :
arrayElement.compareTo(prefix)
If so, you can change it to look like this:
arrayElement.startsWith(prefix) ? 0 : arrayElement.compareTo(prefix)
I suggest looking into the API code for this. There is an Arrays class that you can check out in the java.lang package and learn from there.
Working on a similar problem right now. I believe pseudo code will go something like yours. I created a pojo class Song. A song is made up up three strings artist,title, and lyrics.
When you create a song object you get :
// Artist Title Lyrics..
Song a = ["Farmer Brown", "Oh' Mcdonalad", "Oh'mcdonal had a farm eh i oh i oh"]
public class Song implements Comparable<Song> {
private String _artist;
private String _lyrics;
private String _title;
// constructor
public Song(String artist, String title, String lyrics) {
this._artist = artist;
this._title = title;
this._lyrics = lyrics;
}
public String getArtist() {
return _artist;
}
public String getLyrics() {
return _lyrics;
}
public String getTitle() {
return _title;
}
public String toString() {
String s = _artist + ", \"" + _title + "\"";
return s;
}
//This compare two song objects
public int compareTo(Song song) {
String currentSong = song.toString();
int x = currentSong.compareToIgnoreCase(this.toString());
return x;
}
This is your method here that will take in the array of songs and your prefix and use the compare method to see if they match. If they match the compareTo method returns a 0. If you get a 0 then you know you have found your song so return the arrayOfSongs[index where song is found].
I have not coded up my search yet but I modified yours to match my code. I have not tested it yet. I don't think you even need a compareTo method but you can use it. Also for scaling the binary search should return a list of songs that might match as you might have multiple songs that start with "xyz" . Kind of when you start searching on google with prefix "do" you get a drop down of "dog, donut,double" which gives the user something to choose like a search engine.
public static ArrayList<Song> search (String[] arrayOfSongs , String enteredPrefix) {
ArrayList<Song> listOfMatches = new ArrayList<Song>;
int mid;
int lo = 0;
int hi = arrayOfSongs.length - 1;
while(lo <= hi)
{
mid = (hi + lo) / 2;
if(arrayOfSongs[mid].startsWith(enteredPrefix))
{
System.out.println("Found a match, adding to list");
listOfMatches.add(arrayOfSongs[mid]);
}
}
return listOfMatches;
}
Once you have a listOfMatches of possible suspects of the song you want you can use the compareTo method in some way.