this is what i have so far and what im trying to do i dont know how to access both parts of the split this code is really wrong but i dont know how to do what i want(yes it is for school)
public class Relatives
{
private Map<String,Set<String>> map;
/**
* Constructs a relatives object with an empty map
*/
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
/**
* adds a relationship to the map by either adding a relative to the
* set of an existing key, or creating a new key within the map
* #param line a string containing the key person and their relative
*/
public void setPersonRelative(String line)
{
String[] personRelative = line.split(" ");
if(map.containsKey(personRelative[0]))
{
map.put(personRelative[0],map.get(personRelative[1])+personRelative[1]);
}
else
{
map.put(personRelative[0],personRelative[1]);
}
}
im trying to access the person and add to there current relatives and if the dont exist create a new person with that relative
how would i format it so it returns like this
Dot is related to Chuck Fred Jason Tom
Elton is related to Linh
i have this but get error
public String getRelatives(String person)
{
return map.keySet();
}
You cannot add an item to a Set using the += operator; you must use the add method.
Also, you have to create the set the first time you are going to use it.
The fixed code could look like:
String[] personRelative = line.split(" ");
String person = personRelative[0];
String relative = personRelative[1];
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new HashSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
Related
I have an assingment for school and I am having trouble with some ArrayLists. I have an input file which has one entry at every line. This entry has an integer and up to four strings. This input file is about locations that a film is filmed. The integer is the movieID in my case and the strings are the locations. However not every film has 4 locations which means that when my program tries to load the file it returns an error because it expects 5 fields at every row and this never happens because I have movies with 1 or 2 or the locations. I use a data loader class because I have to load several different files. My other files have a specific number of entries and fields at each row so loading those isn't a problem. The load process is done by adding the file into an array list and then creating the objects needed. I know that I need the program somehow to understand the empty fields and maybe handle them dynamically, for example a movie has 3 locations so the 4th field is empty, but I haven't figured it out yet. Any suggestions? Thank you!
This is my LocationsLoader class.
package dataLoader;
import java.util.ArrayList;
import dataModel.Locations;
public class LocationsLoader extends AbstractFileLoader<Locations>{
public int constructObjectFromRow(String[] tokens, ArrayList<Locations> locations) {
int movieID;
List<String> loc = new List();
movieID = Integer.parseInt(tokens[0]);
loc = tokens[]; // What goes here?
Locations l;
l = new Locations(movieID, loc);
locations.add(l);
System.out.println(l);
//System.out.println(locations.toString());
return 0;
}
}
And this is my Locations class:
package dataModel;
public class Locations {
private int movieID;
private List<String> loc;
public Locations(int otherMovieID, List<String> otherLocations) {
this.movieID = otherMovieID;
this.loc = otherLocations;
}
public int getMovieID() {
return movieID;
}
public void setMovieID(int id) {
this.movieID = id;
}
public String getLocations(int index) {
return loc.get(index);
}
}
}
You fill an array here
String[] tokens = new String[numFields];
for (int i = 0; i < numFields; i++) {
tokens[i] = tokenizer.nextToken();
}
but arrays are fixed length, there's really no reason to use them if you can have fewer values. Fill a list instead.
List<String> tokens = new ArrayList<>();
while (tokenizer.hasNextToken()) {
String token = tokenizer.nextToken().trim();
if (!token.isEmpty()) {
tokens.add(tokenizer.nextToken());
}
}
In fact, I'm not sure why you would need to give the reader the number of expected tokens at all.
But as Dodgy pointed out, you might as well use String#split:
String[] tokens = line.split(delimiter);
which will yield empty Strings as well, but you can just ignore those in your constructObjectFromRow function.
Currently I am self learning java and am doing an exercise in my textbook where it asks to me to take 1000 names in a text file with corresponding phone numbers and basically ask the user what they want to search up.
What my code does right now, is uses the Collections.binarySearch to find Phone numbers, or to find names. However, I was wondering how I could implement my own binary search since, this chapter is basically an introduction to searching and sorting, so I figured I would learn more doing it myself.
Here are the important parts of my code
Here I use the comparable interface
public int compareTo(Item otherObject)
{
Item other = (Item) otherObject;
return key.compareTo(other.key);
}
I then Add Phone Numbers and Names into the ArrayLists via
// Read a line containing the name
String name = in.nextLine();
// Read a line containing the number
String number = in.nextLine();
// Store the name and number in the byName array list
byName.add(new Item(name, number));
// Store the number and name in the byNumber array list
byNumber.add(new Item(number, name));
And then call another method which does
int index = Collections.binarySearch(byName, new Item(k,""));
if(index<0) return null;
return byName.get(index).getValue();
I also have another method which can search byPhone
Thus finding everything correctly.
My Question
What I want to know is how I can implement my own method which will do binarySearch. I've done binary search for just arrays and finding a number in an array, but I'm having difficulties really understanding how the method is going to be set up since we are dealing with objects and array lists.
For example I wanted to make a method like this:
int myBinarySearch(ArrayList<Item> thisItem, Object Item)
{
// search logic here
}
However I am not sure whether this is the right approach. Could someone guide my on how exactly I should format my method for binary search, given the fact that I have a bunch of objects in an arraylist which need to be sorted, as opposed to a simple array.
Currently Working code
Here is the full code for my currently working method using Collections.binarySearch
/Item.java:
/**
An item with a key and a value.
*/
public class Item implements Comparable<Item>
{
private String key;
private String value;
/**
Constructs an Item object.
#param k the key string
#param v the value of the item
*/
public Item(String k, String v)
{
key = k;
value = v;
}
/**
Gets the key.
#return the key
*/
public String getKey()
{
return key;
}
/**
Gets the value.
#return the value
*/
public String getValue()
{
return value;
}
public int compareTo(Item otherObject)
{
Item other = (Item) otherObject;
return key.compareTo(other.key);
}
}
//LookupTable.java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
/**
A table for lookups and reverse lookups
*/
public class LookupTable
{
private ArrayList<Item> byName;
private ArrayList<Item> byNumber;
/**
Constructs a LookupTable object.
*/
public LookupTable()
{
byName = new ArrayList<Item>();
byNumber = new ArrayList<Item>();
}
/**
Reads name and number pairs from the Scanner
and adds them to the byName and byNumber array lists.
#param in the scanner for reading the input
*/
public void read(Scanner in)
{
while (in.hasNextLine())
{
// Read a line containing the name
String name = in.nextLine();
// Read a line containing the number
String number = in.nextLine();
// Store the name and number in the byName array list
byName.add(new Item(name, number));
// Store the number and name in the byNumber array list
byNumber.add(new Item(number, name));
}
// Sort the byName Items so we can binary search
Collections.sort(byName);
// Sort the byNumber Items so we can binary search
Collections.sort(byNumber);
}
/**
Looks up an item in the table.
#param k the key to find
#return the value with the given key, or null if no
such item was found.
*/
public String lookup(String k)
{
// Use the Collections.binarySearch() method to find the
// position of the matching name in the byName array list.
// Return null if position is less than 0 (not found).
// Otherwise, return the number for the found name.
int index = Collections.binarySearch(byName, new Item(k,""));
if(index<0) return null;
return byName.get(index).getValue();
}
/**
Looks up an item in the table.
#param v the value to find
#return the key with the given value, or null if no
such item was found.
*/
public String reverseLookup(String v)
{
// Use the Collections.binarySearch() method to find the
// position of the matching number in the byNumber array list.
// Return null if position is less than 0 (not found).
// Otherwise, return the name for the found number.
int index = Collections.binarySearch(byNumber, new Item(v, ""));
if(index<0) return null;
return byNumber.get(index).getValue();
}
}
//PhoneLookup.java:
import java.io.IOException;
import java.io.FileReader;
import java.util.Scanner;
/* The input file has the format
Abbott, Amy
408-924-1669
Abeyta, Ric
408-924-2185
Abrams, Arthur
408-924-6120
Abriam-Yago, Kathy
408-924-3159
Accardo, Dan
408-924-2236
Acevedo, Elvira
408-924-5200
Acevedo, Gloria
408-924-6556
Achtenhagen, Stephen
408-924-3522
. . .
*/
public class PhoneLookup
{
public static void main(String[] args) throws IOException
{
Scanner in = new Scanner(System.in);
System.out.println("Enter the name of the phonebook file: ");
String fileName = in.nextLine();
LookupTable table = new LookupTable();
FileReader reader = new FileReader(fileName);
table.read(new Scanner(reader));
boolean more = true;
while (more)
{
System.out.println("Lookup N)ame, P)hone number, Q)uit?");
String cmd = in.nextLine();
if (cmd.equalsIgnoreCase("Q"))
more = false;
else if (cmd.equalsIgnoreCase("N"))
{
System.out.println("Enter name:");
String n = in.nextLine();
System.out.println("Phone number: " + table.lookup(n));
}
else if (cmd.equalsIgnoreCase("P"))
{
System.out.println("Enter phone number:");
String n = in.nextLine();
System.out.println("Name: " + table.reverseLookup(n));
}
}
}
}
You can find how JDK does it from JDK source code. In java.util.Collections:
private static <T>
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)
Very same as the one you're working.
A binary search is a very simple algorithm. In pseudo code, it is:
find(list, item):
if list is empty
return not found
get middle item from list
if item matches middle
return middle
else if item is before middle
return find(list before middle, item)
else
return find(list after middle, item)
The list must be sorted to allow this to work. You can use List.subList to avoid having to do any copying or passing indices around.
In your case you want to be able to search by multiple criteria. It would make the most sense if you passed a argument into your method that defines what you are searching for.
I am doing this Java assignment for hours and stuck with this tester class for very almost 5 hours.
In this assignment, I have created a Product class, a Money class, a LineItem class and an Inventory class. Now i need to create a test class to test the program by putting new lineitems into the inventory array.
In the tester class, I am trying to create a static method public static void addTestItems(Inventory theInventory) which suppose to add 4 items. For each item I will need to create a product object followed by a LineItem object to contain the newly created product. next i need to use a method from the inventory class to add the items into the array in the inventory class.
What i have tried too so far:
private static void addTestItems(Inventory theInventory)
{
Inventory[] _items;
Product product1 = new Product("Book","Objects first with Java"," An excellent introductory Java textbook");
Product product2 = new Product("CD","The dark side of the moon","The all-time classic Pink Floyd album");
Product product3 = new Product("DVD", "Transformers","Robots in disguise");
Product product4 = new Product("Laptop","Lenovo T42","A good yet affordabble laptop");
Money unitPrice1 = new Money(29,99);
Money unitPrice2 = new Money(4,99);
Money unitPrice3 = new Money(9,99);
Money unitPrice4 = new Money(450,0);
_items[0] = new LineItem(product1,5,unitPrice1);
_items[1] = new LineItem(product2,8,unitPrice2);
_items[2] = new LineItem(product3,200,unitPrice3);
_items[3] = new LineItem(product4,9,unitPrice4);
}
The current error is incompatible types- found LineItem but expected Inventory so i tried changing Inventory[] _items; to LineItem[] _items;. But the error was variable _items may not be initialise.
Sorry guys I am a real noob in Java, I tried searching on-line for ages but I do not quite understand most results. The only one i understand was http://forums.devshed.com/java-help-9/bluej-compiler-error-cannot-find-symbol-variable-object-688573.html but i tired putting into my context but failed. I also found lot of results but they had constructors and instance variables in them which my teacher specifically mentioned that I will not need them.
Wonder if expert could guide me along like let me know my mistakes. Thanks thanks.
The inventory class:
/**
* In the Inventory class, it is merely to create a list / array of product which allows the information from the linitem to be put with an index.
* For example, for the first product, we can use the inventory class to input it into the index 1. and he next product into index 2 and so on.
* It is suse to create an array and inputing the lineitem information into it.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Inventory
{
// instance variables - replace the example below with your own
private LineItem[] _items;
private int _numItems;
/**
* Constructor for objects of class Inventory
*/
public Inventory()
{
// initialise instance variables
_items = new LineItem[1000];
_numItems = 0;
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public void addItem(LineItem item)
{
_items[_numItems]= item;
_numItems++;
}
public String toString()
{
String result="";
int i=0;
while (i < _numItems)
{
result = result + _items[i] + "/n";
i++;
}
return result;
}
public void print()
{
String myResult=this.toString();
System.out.println(myResult);
}
public Money getTotalValue()
{
int i=0;
Money total= new Money(0);
while (i<_items.length)
{
total = total.add(Money.NO_MONEY);
i++;
}
return total;
}
public LineItem getItem(String productName)
{
int i = 0;
LineItem itemDetails = null;
while (i<_items.length)
{
if (_items[i].equals(productName))
{
itemDetails= _items[i];
}
else
{
//do nothing
}
i++;
}
return itemDetails;
}
}
I have yet to comment on the methods yet but will do so once i understand it.
Your array is of type Inventory[] - but you're trying to assign references of type LineItem. You're also not initializing it. Change this:
Inventory[] _items;
to this:
LineItem[] _items = new LineItem[5];
And all should be well - although you're not using index 0 (which is why you need it to be size 5) and you're not doing anything with the array afterwards either...
Another alternative to using an array is to use a List:
List<LineItem> items = new ArrayList<LineItem>();
items.add(new LineItem(product1, 5, unitPrice1));
items.add(new LineItem(product2, 8, unitPrice2));
items.add(new LineItem(product3, 200, unitPrice3));
items.add(new LineItem(product4, 9, unitPrice4));
... next think about what you actually want to do with the items variable.
LineItem[] _items = new LineItem[4];
then the index starts from 0 not from 1,
_items[4]
will return indexoutofbounds error
A few things:
incompatible types- found LineItem but expected Inventory
is caused by the fact that your array is supposed to contain Inventory objects but you're assigning LineItems to it instead
variable _items may not be initialise
means that you have your _items object but you haven't initialized it to anything. You want to do
LineItem[] _items = new LineItem[4];
PS: If you want dynamically sized arrays, don't know how many line items you'll potentially load, etc etc use a vector or a collection or something along those lines.
Also,
_items[1] = new LineItem(product1,5,unitPrice1);
_items[2] = new LineItem(product2,8,unitPrice2);
_items[3] = new LineItem(product3,200,unitPrice3);
_items[4] = new LineItem(product4,9,unitPrice4);
In Java, array elements start with index 0 and not 1
_items
is a wonky variable name that makes your team mates sneeze in your coffee
I don't think i have the terminology correct, haven't been one for that. What i'm trying to do is get a string back , then use it to run functions. .. Example :
int slotNumber = ((j*3)+i+1);
String slotString = "slot"+slotNumber;
Regularly I can do this :
slot12.Draw();
And I want to be able to do this :
slotString.Draw();
With it substituting slotString with slot12 in a dynamic scenario. If i truly have to i could do something similar to :
if (slotString == slot1) slot1.Draw();
if (slotString == slot2) slot2.Draw();
And such, but i dont really want to use x number of lines for x number of slots.
Any help is appreciated :D
A possible solution would be to use a HashMap where the key is the slotNumber and the value points to the slot. Then you could do something like the following.
//Initialize at the start of your program
HashMap<int, Slot> SlotHash = new HashMap<int, Slot>();
//Code to retrieve slot and call Draw().
Slot select = SlotHash.get(slotNumber);
select.Draw();
Maybe use a Map if your slots are sparsely-packed. If they're densely-packed, you might be able to use an array of slots. In either case, you do the slot lookup based on index and then call Draw on the looked-up slot.
You would have something like this:
Slot slot1 = new Slot("slot1");
Slot slot2 = new Slot("slot2");
SlotController controller = new SlotController();
controller.add(slot1);controller.add(slot2);
String someSlotNumber = ".....";
controller.draw(someSlotNumber);
See the definition of the classes below:
class SlotController {
Map<String, Slot> slotMap = new HashMap<String, Slot>();
public void addSlot(Slot aSlot) {
slotMap.put(aSlot.getSlotName(), aSlot);
}
public void draw(String slotName) {
slotMap.get(slotName).draw();
}
}
class Slot {
private String slotName;
public Slot(String name){
slotName = name;
}
public String getSlotName() {
return slotName;
}
public void draw() {
}
}
Am having a problem accessing the data in a HashMap. It was created in one class and is being called from another. See below;
Created
public class LoadDatabase {
public Map virusDatabase = new HashMap();
...
public void toHash(String v_Name, String signature) {
virusDatabase.put(v_Name, signature);
}
...
public void printDatabase() { // This method is displaying correct data, so is being stored.
Iterator iterator = virusDatabase.keySet().iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
System.out.println(key + " = " + virusDatabase.get(key));
}
}
...
}
Need Access
public class LCS {
LoadDatabase lb = new LoadDatabase();
Tokenizer T = new Tokenizer();
...
public void buildDataLCS(String[] inTokens) {
Iterator iterator = lb.virusDatabase.keySet().iterator();
...
while (iterator.hasNext()){
String key = (String) iterator.next();
String v_sig = (String) lb.virusDatabase.get(key);
System.out.println(v_sig); //Example of problem, nothing printed
...
}
...
}
Why is the problem happening? Could you point me in the right direction.
Either of the 2 issues,
You are not putting anything there. As I can't see your invocation of toHash(String v_Name, String signature) method.
You are using 2 different instances of LoadDatabase class, somehow. Try making LoadDatabase singleton.
Carlos
I suspect you are not putting what you think you are putting into the map, or the keys when you put data in are not the same as when you take values out. I would log/print the key/val you put in, and then log/print the key/val you try to get out.