adding and deleting from ordered Arraylist - java

I need to add an Object to an ordered ArrayList depending on an attribute inside of the Object. I know how to use the .add method to add the object but I don't know how to search for the right place for it using the compareTo() method. And also I need to remove an Object from the ArrayList if the Object contains a certain String but I cant figure out how to access the Object attributes from the ArrayList.
Realtor Object
/**
* Constructor for Realtor object using parameter
* #param readData - array of data from line
*/
public Realtor(String[]readData){
licenseNumber = readData[2];
firstName = readData[3];
lastName = readData[4];
phoneNumber = readData[5];
commission = Double.parseDouble(readData[6]);
}
RealtorLogImpl
public class RealtorLogImpl {
private ArrayList<Realtor> realtorList;
/**
* Add Realtor object to ordered list
* #param obj - Realtor object
*/
public void add(Realtor obj){
//needs to be added into correct place depending on Realtor licenseNumber
realtorList.add(obj);
}
/**
* Delete Realtor object from list if license matches
* and return true if successful
* #param license
* #return
*/
public boolean remove (String license){
//need to remove Realtor with specific licenseNumber and return true if successful
}

I'm assuming you are using java 8. Some of these things have not been implemented in java 7 so keep that in mind.
First, to remove the items I would recommend using the removeif() method on the arraylist. This takes a lambda expression which could be something like x -> x.getString().equals("someString").
Second, You could add the object to the array then simply sort the array afterwards. You would just have to write a comparator to sort it by.

Here is some basic code; I have no compiler here, so you might find small errors/typos.
I'm sure there are better classes you can use instead of managing your own ordered list.
To insert:
public bool add(Realtor obj) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(item.licenseNumber)) {
return false; // Already there
}
if (s.licenseNumber.compareTo(item.licenseNumber) > 0) {
orderedList.add(idx, item);
return true; // Inserted
}
idx++;
}
orderedList.add(item);
return true; // Appended
}
To delete:
public bool deleteItem(String license) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(license)) {
realtorList.remove(idx);
return true; // Removed
}
}
return false; // Not found
}

To answer your question check the following snippet (requires Java 8) and adapt on your demand:
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Element 1");
list.add("Element 2");
list.add("Element 3");
/*
* Insert at a specific position (add "Element 2.5" between "Element 2" and "Element 3")
*/
Optional<String> elementToInsertAfter = list.stream().filter(element -> element.equals("Element 2")).findFirst();
if(elementToInsertAfter.isPresent()) {
list.set(list.indexOf(elementToInsertAfter.get()) + 1, "Element 2.5");
}
/*
* Remove a particular element (in this case where name equals "Element 2")
*/
list.removeIf(element -> element.equals("Element 2"));
}
#add(element) just adds an element to the list. In case of an ArrayList it's added at the end. If you want to insert an element at a particular position you need to use #set(index,element)
But instead of inserting your element at a particular position manually you should maybe use a comparator instead. See java.util.List.sort(Comparator<? super E> e)

Related

How to provide an object as well as a method reference to an object of that class?

I have written a method which creates an input menu for the console, which displays multiple options for the user to choose from and returns the option which the user has chosen. The method accepts an array of objects, and will display them by calling the toString() method on them. The problem is, that in some cases I don't want to call the toString() method on these objects, but maybe the getName() method. Therefore I want to make it possible to pass a method reference, which can be called on the objects and will return a String.
Then I could f.e. pass an array of persons and the getFullName() method. The persons would be displayed with their full name on the console, but I would still get the person object returned, I wouldn't have to find the person object by its full name.
Here is my current code for the method:
/**
* Prints the provided question and the options to choose from
*
* #param question
* the question to ask the user
* #param options
* list of objects the user can choose from
* #return chosen object
*/
public Object getMultipleChoiceResult(String question, List<?> options) {
int result = 0;
while (result > options.size() | result < 1) {
System.out.println(question);
for (int i = 1; i <= options.size(); i++) {
System.out.println("(" + i + ") " + options.get(i - 1).toString());
}
try{
result = scanner.nextInt();
} catch (InputMismatchException e) {
System.err.println("wrong input");
scanner.next();
}
}
return options.get(result - 1);
}
Do you understand what I am looking for and is it possible?
I think you're looking for this:
public <T> T getMultipleChoiceResult(String question, List<T> options, Function<T, String> toString) {
// ...
System.out.println("(" + i + ") " + toString.apply(options.get(i - 1)));
// ...
}
In your example, you can call it like this:
Object result = getMultipleChoiceResult(question, options, Object::toString);
Or you can pass a list of Person and print Person.getFullName():
Person result = getMultipleChoiceResult(question, persons, Person::getFullName);
There are many ways of achieving this. A relatively modern approach is to pass a method reference:
private static <T> void showList(List<T> list, Function<T,String> f) {
for (T t : list) {
System.out.println(f.apply(t));
}
}
The call to this method would look as follows:
showList(myList, MyType::getFullName);
The above assumes that myList is a List<MyType>, and MyType has a non-static method getFullName() returning a String.
Demo.

Check for multiple instances of same object in array

i am looking for a way to check if an array contains more than 1 instances of the same object. I've been looking around but can't seem to find anything in the javadoc nor stackoverflow.
I am creating a monopoly board game (or in danish, matador) where the fee from landing on one of the fields differs depending on how many of that type of field the player owns.
I have a list in my player class in which i put all the fields that the player buys:
public List<OwnableField> ownsList = new ArrayList<>();
public void buy(OwnableField ownable) {
pay(ownable.getPrice());
ownsList.add(ownable);
}
And then i have this method in the specific field class, in which i am working on an if statement to set the fee:
public int fee;
public int feeCalc(int diceScore) {
if(this.getOwner().ownsList.(whatever checks for duplicate object in array)){
fee = 200 * diceScore;
} else {
fee = 100 * diceScore;
}
return fee;
}
If you have a proper equals and hash code defined then you can use sets to achive that
List list = ...
if(new HashSet(list).size().equals(list.size()){
//same size
} else {
//there was a duplicated element
}
If you want to check for one specific object only you could do it with:
final Object someObject = ...
List list = ...
int size = FluentIterable.from(list).filter(new Predicate<Object>() {
#Override
public boolean apply(Object input) {
return input == someObject;
}
}).size();
if(size > 1) {
//there is a duplicated element
}
Or, if you are looking for an instance of a class, then try:
List list = ...
int size = FluentIterable.from(list).filter(Predicates.instanceOf(YourClass.class)).size();
if(size > 1) {
//there is a duplicated element
}

right way to use collections in Java?

I have the following code. However I am doubting about if it is the right way to implement it or not.
What I mean is: in the collection framework there are many data structures to use and creating the class (MemberList) to manage the aggregations of many members can be implemented using ArrayList, LinkedList, priority queue ...
I would like to use a data structure that fits with my needs, and that has the least Big O possible when it comes to searching, sorting, deleting, adding, modifying and deleting.
public class MemberList{
/**
*a list of accounts existing in the database
*/
private static List<Member> members = new ArrayList<Member>();
/**
* add a member to our member list
* #param m the member to be added
*/
public static void Add(Member m)
{
members.add(m);
/**
* delete a member from our member list
* #param m the member to be deleted
*/
public static void Delete(Member m)
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
if(m.equals(it.next()))
{
it.remove();
}
}
}
/**
* Search for a specific member in the member list
* #param m the member that needs to be found
* #return the reference of the object Member
* #throws UserNotFoundExeption whether the member was not found in the list
*/
public static Member Search (Member m) throws UserNotFoundExeption
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
if(m.equals(it.next()))
{
return it.next();
}else{
UserNotFoundExeption ex = new UserNotFoundExeption(it.next().getUsername());
throw ex;
}
}
return null;
}
/**
* The login method enables checking whether the login was made successfully or not. if not, it can throw two
* exceptions to handle the errors
* #param member
* #return
* #throws UserNotFoundExeption
* #throws FailedLoginException
*/
public static boolean login (Member m)
throws UserNotFoundExeption,FailedLoginException {
try{
Member member = Search(m);
if (!m.authenticate(member.getPassword()))
{
FailedLoginException ex2 = new FailedLoginException (member.getPassword());
throw ex2;
}
else
{
return true;
}
}catch(UserNotFoundExeption ex){
throw ex;
}
}
/**
* this behavior modify attributes of the corresponding class
* #param <T> this generic helps to accept any type of parameter change, hence we can change any type
* #param m this is the member that need to change his information
* #param choice the choice of which information to change
* #param change the new change on the member attribute
* #throws UserNotFoundExeption
*/
public static <T> void Modify(Member m, int choice, T change) throws UserNotFoundExeption
{
try{
Member member = Search(m);
switch(choice)
{
case 1:
member.setUsername((String)change);
break;
case 2:
member.setPassword((String)change);
break;
case 3:
member.setCommunity((Community)change);
break;
}
}catch(UserNotFoundExeption ex){
throw ex;
}
}
/**
* display the member list objects information
*/
public static void Display()
{
Iterator<Member> it = members.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
/**
* Sort objects in the list
*/
public static void Sort()
{
Iterator<Member> it = members.iterator();
Member[] Members_Array = members.toArray(new Member[members.size()]);
Member temp;
for(int i = 0; i<members.size(); i++)
{
for(int j = 0; j < members.size() - (i+1); j++)
{
if(Members_Array[j].compareTo(Members_Array[j+1]) > 0)
{
temp = Members_Array[j];
Members_Array[j] = Members_Array[j+1];
Members_Array[j+1] = temp;
}
}
}
}
}
Thank you!
This question is too broad, and "the right way to use collections in Java" is also a philosophical question, so it cannot be scientifically answered.
Specifically to your case, depending on the pool of your members, you probably don't want to iterate over them when you need to pull a member out. I would recommend you use something like a HashMap<String,Member>, where each member has an identifiable unique key (a username for instance). This will grant you O(1) access speed and allow you to iterate when you need it using .values().
You can use a HashMap like so:
// This is how you create a hash map:
HashMap<String,Member> members = new HashMap<String,Member>();
// This is how you add an object to it. It is slower than lists,
// but since reading happens far often, it pays off.
members.put("ben", new Member());
// This is how you access an object in the hash map.
// Accessing a hash map is O(1).
Member member = members.get("ben");
// This is how you remove an object from the hash map.
// Removing an object is also O(1)
members.remove("ben");
// Hash maps are also iterable
for(Member member : members.values()) {
}
I would use array list if you dont want to use JDBC.
But later if your project going to growe, you have to use JDBC.

Binary tree variable type issue

I'm having trouble with a method I wrote to insert string words into a binary tree. The below code is the method in question. Basically, the word is inserted if it is not yet in the tree (as a BinaryTreeNode), and if it is in the tree, its frequency (count variable within BinaryTreeNode) is increased by one. My problem is with the temporary variable searchWord. Defining it as a String creates a type mismatch and a statement that says getFrequency() is not defined for type String. The generic type T is only there as a placeholder - it too does not work. What should it therefore be defined as?
buildBinaryTree method:
public static void buildBinaryTree(String word) {
//if word is already in tree
if(wordTree.contains(word)) {
//find existing word node
T searchWord = wordTree.find(word); //problem here
//increment frequency by 1
searchWord.setFrequency(searchWord.getFrequency() + 1);
} else {
//add word to tree
System.out.println(word);
wordTree.addElement(word);
}
}
BinaryTreeNode constructor:
/**
* Creates a new tree node with the specified data.
* #param obj the element that will become a part of the new tree node
*/
BinaryTreeNode(T obj) {
element = obj;
left = null;
right = null;
frequency = 1;
}
Frequency get/set methods:
/**
* Gets the frequency.
* #return the frequency
*/
public int getFrequency() {
return frequency;
}
/**
* Sets the frequency.
* #param frequency the frequency to set
*/
public void setFrequency(int frequency) {
this.frequency = frequency;
}
After talking in chat, you should define a class that has both a String and int that you use as the type to place in the binary tree, to replace the type variable T. Then, you can define methods such as getString() to return the String, incrementFrequency() to add one to the frequency, etc. When you get an object out of the binary tree, it will be the right type to call these methods.

Searching through an ArrayList

Implement a method
public void search (String searchString) { }
to iterate through the notes ArrayList until it
finds a note that contains the searchString.
It should then print either the item found or
the message "String not found".
So far, I have:
import java.util.ArrayList;
import java.util.Iterator;
/**
* A class to maintain an arbitrarily long list of notes.
* Notes are numbered for external reference by a human user.
* In this version, note numbers start at 0.
*
* #author David J. Barnes and Michael Kolling.
* #version 2008.03.30
*/
public class Notebook
{
// Storage for an arbitrary number of notes.
private ArrayList<String> notes;
/**
* Perform any initialization that is required for the
* notebook.
*/
public Notebook()
{
notes = new ArrayList<String>();
}
/**
* Store a new note into the notebook.
* #param note The note to be stored.
*/
public void storeNote(String note)
{
notes.add(note);
}
/**
* #return The number of notes currently in the notebook.
*/
public int numberOfNotes()
{
return notes.size();
}
/**
* Show a note.
* #param noteNumber The number of the note to be shown.
*/
public void showNote(int noteNumber)
{
if(noteNumber < 0) {
// This is not a valid note number, so do nothing.
System.out.println("invalid index given");
}
else if(noteNumber < numberOfNotes()) {
// This is a valid note number, so we can print it.
System.out.println(notes.get(noteNumber));
}
else {
System.out.println("there are fewer items in the notebook");
// This is not a valid note number, so do nothing.
}
}
public void removeNote(int noteNumber)
{
if(noteNumber < 0) {
// This is not a valid note number, so do nothing.
System.out.println("invalid index given");
}
else if(noteNumber < numberOfNotes()) {
// This is a valid note number.
notes.remove(noteNumber);
}
else {
System.out.println("there are fewer items in the notebook");
// This is not a valid note number, so do nothing.
}
}
/* Edit note.
* I tried to improve the formatting of the code below, but I'm completely
* unable to figure out how on earth anything of that should make sense
* and therefore the indentation is completely without any meaning.
*/
public void search (String searchString)
{
for each notes in ArrayList {
if notes = searchString;
System.out.println("String found"); + searchString
return end
}
if}
System.out.println("String not found");
}
}
But it is not working, and I am not able to work it out.
Several problems:
Your search method is actually outside the class.
The body of your search method makes no sense at all.
If you're counting on the monkeys writing Shakespeare, you'll be waiting a while.
To iterate over the array list, you can use a 'for-each' loop:
for (String note: notes) {
// Do something with note
}
This is very basic syntax. Have you seen it before? If not, you should start by reading a very basic tutorial to Java before attempting this homework.
Fundamentally you need to look at each item in your ArrayList and test to see if it matches the search condition. In Pseudocode
for each note in notes
{
if note equals searchString then
print "Found " + searchString
return
end if
}
print "not found"
Given that basic outline, want to take a second stab at coding it in Java?
Basically you want to loop over the elements, and for each one check whether it equals the element you are searching for. You can use a for loop or a foreach loop to do the actual iteration.
should you be checking if the whole note matches your searchstring, or if the note contains your searchstring?
i.e. given notes "foobar","baz","spam", should a search on "foo" return "foobar" or not match on anything?
so in pseudocode:
for each note in notes
{
if searchstring in note
{
print "Found :"+note
}
}
check this website http://pleac.sourceforge.net/pleac_java/arrays.html it may be useful

Categories