As the question reads.... and I do NOT want to use multiple maps, just one map.
My goal is to get a list of the names I enter in the input.
I have tried like a hundred different for-loops, but I always tend to end up with a list of the whole map and/or that the duplicate key is overridden.
import java.util.*;
public class Another {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String name;
HashMap<String, ToA>wordkey = new HashMap<String, ToA>();
ToA a = new ToA("Doolin", "Bill", "18580824-1464");
ToA b = new ToA("Dalton", "Bob", "18701005-2232");
ToA c = new ToA("James", "Jesse", "18470905-2401");
ToA d = new ToA("Dalton", "Emmet", "18710713-0818");
wordkey.put("Doolin", a);
wordkey.put("Dalton", b);
wordkey.put("James", c);
wordkey.put("Dalton", d);
System.out.println("Efternamn:");
name = scan.next();
}
}
public class ToA{
private String fname, lname, dob;
public ToA(String fname, String lname, String dob){
this.fname = fname;
this.lname = lname;
this.dob = dob;
}
public String getFname(){
return fname;
}
public String getLname(){
return lname;
}
public String getDob(){
return dob;
}
public String toString(){
return "\nFirstname: " + fname + "\nSurname: " + lname + "\nDateOfBirth: " + dob;
}
}
For inputting Dalton, I would like the output
Firstname: Bill
Surname: Dalton
DateOfBirth: 18701005-2232
Firstname: Emmet
Surname: Dalton
DateOfBirth: 18710713-0818
I'm really stuck with this so any help is highly appreciated, Thanks
To post my comment as an answer: use a Map<String, List<ToA>> like this:
Map<String, List<ToA>> wordkey = new HashMap<>();
ToA a = new ToA("Doolin", "Bill", "18580824-1464");
ToA b = new ToA("Dalton", "Bob", "18701005-2232");
ToA c = new ToA("James", "Jesse", "18470905-2401");
ToA d = new ToA("Dalton", "Emmet", "18710713-0818");
wordkey.put("Doolin", Arrays.asList(a));
wordkey.put("James", Arrays.asList(c));
wordkey.put("Dalton", Arrays.asList(b, d));
To print the names based on the input, you can do something like this:
System.out.println("Efternamn:");
name = scan.next();
List<ToA> toas = wordkey.get(name);
if (toas != null) {
System.out.println("ToAs");
for (ToA toa : toas) {
System.out.println("ToA: " + toa);
}
}
else {
System.out.println("No ToAs found for input: " + name);
}
There are several possibilities for what you are trying to achieve. A simple one would be to use Guavas Multimap or to use Apaches MultiMap.
Another possibility is to "wrap" the Map in a class and keep a List<ToA> as Value of the Map. You'd override the put, remove and get methods to what you need
Related
Here is my code:
public static Map<String, List<Customer>> readCustomerData() throws IOException {
Map<String, List<Customer>> customers =
Files.lines(Paths.get("customer.csv"))
.map(line -> line.split("\\s*,\\s*"))
.map(field -> new Customer(
Integer.parseInt(field[0]), field[1],
Integer.parseInt(field[2]), field[3]))
.collect(Collectors
.groupingBy(Customer::getName));
System.out.println (customers);
return customers;
}
I notice that this code read my data in the csv file into one element like this:
(Ali = ["1 Ali 1201345673 Normal"] , Siti = ["2 Siti 1307891435 Normal"])
But in my thinking , I would like to read the data like the array list such as for Ali: 1 is an element , Ali is an element , 1201345673 is an element and Normal is another element in the list in the Map customer. How can I modify my code to do such a thing?
This is my Customer class just in case:
public class Customer {
private int customerNo;
private String name;
private int phoneNo;
private String status;
public Customer () {}
public Customer (int customerNo, String name, int phoneNo, String status){
this.customerNo = customerNo;
this.name = name;
this.phoneNo = phoneNo;
this.status = status;
}
public String getName(){
return name;
}
public String toString(){
return customerNo + " " + name + " " + phoneNo + " " + status;
}
Here is my csv file:
1,Ali,1201345673,Normal
2,Siti,1307891435,Normal
Thank you for your attention.
Assuming that the customer names are unique, there's no need to return a Map<String, List<Customer>>, since each List will contain a single Customer.
You can change your code to:
Map<String, Customer> customers =
Files.lines(Paths.get("customer.csv"))
.map(line -> line.split("\\s*,\\s*"))
.map(field -> new Customer(
Integer.parseInt(field[0]), field[1],
Integer.parseInt(field[2]), field[3]))
.collect(Collectors.toMap(Customer::getName, Function.identity()));
And if the names are not unique, you can index the customers by the customer IDs.
As for I would like to read the data like the array list such as for Ali: 1 is an element , Ali is an element , 1201345673 is an element and Normal is another element in the list in the Map customer - this doesn't make sense to me. You already create a Customer object from each line of your input, which is much more useful and type safe compared to a List of properties.
My .txt file is
code1,description1,price1
code2,description2,price2
etc.
Using:
ArrayList<String> items = new ArrayList<String>();
String description;
File fn = new File("file.txt");
String[] astring = new String[4];
try{
Scanner readFile = new Scanner(fn);
Scanner as = new Scanner(System.in);
while (readFile.hasNext()){
astring = readFile.nextLine().split(",");
String code = astring[0];
items.add(code);
description = astring[1];
}
}catch(FileNotFoundException){
//
}
for(String things: items){
System.out.println("The code is: " + things + "The description is " + description);
}
My output prints out
code1 description1
code2 description1
code3 description1
I'm trying to figure out how to make the description update as the code's do. e.g.
code1 description1
code2 description2
code3 description3
If this question has been asked already, I apologize. I couldn't find out how to do it by searching around but if there's a reference to figure this out I'll close this down and go there. Thanks in advance!
The problem is with your logic. You are storing only astring[0] to the items ArrayList and overwriting the value of description each time. As a result on last value read is stored in description which you are printing in the loop.
I prefer creating a custom class as follows. (Just for the sake of demo otherwise you would declare your fields as private and provide getters and setters)
class MyObject {
public String code;
public String description;
public String price;
}
now instead of creating ArrayList of Strings you will create ArrayList of MyObject as follows
ArrayList<MyObject> items = new ArrayList<MyObject>();
now create a new instance of MyObject each time you read a line , populate its fields with the values from astring as follows
ArrayList<MyObject> items = new ArrayList<MyObject>();
File fn = new File("test.txt");
String[] astring = new String[4];
try {
Scanner readFile = new Scanner(fn);
Scanner as = new Scanner(System.in);
MyObject myObject;
while (readFile.hasNext()) {
astring = readFile.nextLine().split(",");
myObject = new MyObject();
myObject.code = astring[0];
myObject.description = astring[1];
myObject.price = astring[2];
items.add(myObject);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
and then finally print it using the same foreach loop as follows
for (MyObject item : items) {
System.out.println("The code is: " + item.code + " The description is: " + item.description + " The price is: " + item.price);
}
Output
The code is: code1 The description is: description1 The price is: price1
The code is: code2 The description is: description2 The price is: price2
The reason you're seeing that output is that you are not saving description along with the code inside the list, that is why the last description is saved within the description variable not all description values.
To solve this problem, you can create a simple Java Bean/POJO class
and wrap your data inside it and then you can simply fetch the value
you have saved it and then show it properly. Take a look at the code
below:
public class Launcher{
public static void main(String[] args) {
ArrayList<Item> items = new ArrayList<Item>();
File fn = new File("file.txt");
try {
Scanner readFile = new Scanner(fn);
while (readFile.hasNext()) {
String[] astring = readFile.nextLine().split(",");
String code = astring[0];
String description = astring[1];
String price = astring[2];
Item item = new Item(code, description, price);
items.add(item);
}
} catch (FileNotFoundException d) { // }
}
for (Item thing : items) {
System.out.println(String.format("The code is: %s\tThe description is: %s\tThe Price is %s",thing.getCode(),thing.getDescription(), thing.getPrice()));
}
}
}
class Item {
private String code;
private String description;
private String price;
public Item(String code, String description, String price) {
this.code = code;
this.description = description;
this.price = price;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
public String getPrice() {
return price;
}
}
I'm learning java and trying to implement two java classes.
Student: firstName, lastName, departmentIn, yearGraduation, an array of UAClass this student is taking, an array of integers corresponding to the grades received for these classes
UAClass: teacherFirstName, teacherLastName, semesterOffered, numCredits
In the Student class, implement a method that calculates GPA. In the Student’s main() method, initiate one Student object and print out her GPA.
In my student.java class I have:
import java.util.*;
public class Student {
private String firstName;
private String lastName;
private String departmentIn;
private String yearGraduation;
private float [] grade;
private int counter = 0;
private String Student;
public Student(String my_firstName, String my_lastName, String my_deptIn, String my_yearGrad) {
firstName = my_firstName;
lastName = my_lastName;
departmentIn = my_deptIn;
yearGraduation = my_yearGrad;
grade = new float[5];
}
public String toString(){
String value;
value = "First Name: " + firstName + "\n";
value += "Last Name : " + lastName + "\n";
value += "Department: " + departmentIn + "\n";
value += "Grad. Year: " + yearGraduation + "\n";
return value;
}
public static void main(String[] args) {
Student my1 = new Student("Bob", "Hope", "MBA", "2018");
Student my2 = new Student("John", "Smith", "MBA", "2020");
Student my3 = new Student("Jane", "Doe", "MBA", "2021");
UAClass cy1 = new UAClass[4];
String[] secondArray = cy1.getarrayClass();
System.out.println(my1);
System.out.println(my2);
System.out.println(my3);
System.out.println(Arrays.toString(cy1));
}
}
And in my UAClass.java class I have:
import java.util.*;
public class UAClass {
private String teacherFirstName;
private String teacherLastName;
private String semesterOffered;
private String numCredits;
private String[] arrayClass = {"MBA 501","MBA 505","MBA 513","MBA 545"};
public UAClass(String teacherF, String teacherL, String semesterO, String numC) {
teacherFirstName = teacherF;
teacherLastName = teacherL;
semesterOffered = semesterO;
numCredits = numC;
}
public String[] getarrayClass(){
return arrayClass.clone();
}
}
What I am trying to do is to create an Array in 'UAClass' and having it printed into 'Student' but I can't seem to get it working.
I've modified the code as Amit suggested. When I run it, I get this error.
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: Array.getarrayClass at Homework2.Student.main(Student.java:66)
It seems to be having an issue with String[] secondArray = cy1.getarrayClass();
I took out the line String[] secondArray = cy1.getarrayClass() and it seems to run fine but now all I get is [null, null, null, null]
First of all, your UAClass has one constructor that takes String teacherF, String teacherL, String semesterO, String numC as parameters.
So you need to call this constructor like this:
UAClass cy1 = new UAClass("Teacher F", "Teacher L", "Semester", "NumC");
Secondly, you use an String[] type. This is a low-level array type. You can do this in Java, but normally people rather use a List type, and then not the raw type, but better like List<String>. List is actually an interface, but you can reference it as the Arrays class returns an implementation of the List class.
You should then use:
private List<String> arrayClass = Arrays.asList("MBA 501","MBA 505","MBA 513","MBA 545");
And you return a clone of the array. I presume you do this because you don't want the array to be changed. I would just return a concatenated String with values. Here is a nice example with a stream.
public String getClasses() {
return arrayClass.stream().collect(Collectors.joining(","));
}
Now in the Student class you can just print the list of classes like this:
System.out.println(cy1.getClasses());
When you change your code like that it will work but I couldn't understand what you are trying to do in your code.
UAClass cy1 = new UAClass("Bob", "", "", "");
String[] secondArray = cy1.getarrayClass();
System.out.println(my1);
System.out.println(my2);
System.out.println(my3);
System.out.println(cy1.getarrayClass());
Map<Object,String> mp=new HashMap<Object, String>();
Scanner sc=new Scanner(System.in);
System.out.println("Enter the instrument name");
String name=sc.next();
mp.put(name, "Control Valve");
mp.put(name, "BDV");
mp.put(name, "SDV");
mp.put(name, "ON-OFF VALVE");
mp.put(name,"Analyser");
Set s=mp.entrySet();
Iterator it=s.iterator();
while(it.hasNext())
{
Map.Entry m =(Map.Entry)it.next();
String key=(String)m.getKey();
String value=(String)m.getValue();
System.out.println("Instrument name :"+key+" fields:"+value);
}
}
}
In this only last value is mapped to the key .i.e analyser to key .
How to map all the values to one key entered by the user .And also it has to ask user to enter values for each value field.
updated code -:It asks for instrument name but then shows exception "java.util.ArrayList cannot be cast to java.lang.String"
Map<String,List<String>> mp=new HashMap<String,List<String>>();
Scanner sc=new Scanner(System.in);
System.out.println("Enter the instrument name");
String name=sc.next();
List<String> valList = new ArrayList<String>();
valList.add("Control Valve");
valList.add("BDV");
valList.add("SDV");
valList.add("ON-OFF VALVE");
valList.add("Analyser");
mp.put(name, valList);
Set s=mp.entrySet();
Iterator it=s.iterator();
while(it.hasNext())
{
Map.Entry m =(Map.Entry)it.next();
String key=(String)m.getKey();
String value=(String)m.getValue();
System.out.println("Instrument name :"+key+" fields:"+value);
}
}
}
I would suggest to use
Map<Object,List<String>> mp=new HashMap<Object, List<String>>();
So that you can maintain set of values to a given key.
if a list available for given key , get the list and add the new value to list.
UPDATED
Map<String,List<String>> mp=new HashMap<String,List<String>>();
Scanner sc=new Scanner(System.in);
System.out.println("Enter the instrument name");
String name=sc.next();
List<String> valList = new ArrayList<String>();
valList.add("Control Valve");
valList.add("BDV");
valList.add("SDV");
valList.add("ON-OFF VALVE");
valList.add("Analyser");
mp.put(name,valList);
for(String key : mp.keySet()){
System.out.print("Instrument name :"+key+" Values : ");
for(String val : mp.get(key)){
System.out.print(val+",");
}
}
I suspect you should be using a custom class with a field for each piece of information you need. This can be added once into the map for each name
public static void main(String... args) {
Map<String, MyType> mp = new LinkedHashMap<String, MyType>();
Scanner sc = new Scanner(System.in);
System.out.println("Enter the following comma separated with a blank line to stop.");
System.out.println("instrument name, Control Value, BDV, SDV, ON-OFF VALVE, Analyser");
for (String line; (line = sc.nextLine()).length() > 0; ) {
MyType mt = new MyType(line);
mp.put(mt.getName(), mt);
}
System.out.println("you entered");
for (MyType myType : mp.values()) {
System.out.println(myType);
}
}
static class MyType {
private final String name, controlValue, bdv, sdv, onOffValue, analyser;
MyType(String line) {
String[] parts = line.trim().split(" *, *");
name = parts[0];
controlValue = parts[1];
bdv = parts[2];
sdv = parts[3];
onOffValue = parts[4];
analyser = parts[5];
}
public String getName() {
return name;
}
public String getControlValue() {
return controlValue;
}
public String getBdv() {
return bdv;
}
public String getSdv() {
return sdv;
}
public String getOnOffValue() {
return onOffValue;
}
public String getAnalyser() {
return analyser;
}
#Override
public String toString() {
return "MyType{" +
"name='" + name + '\'' +
", controlValue='" + controlValue + '\'' +
", bdv='" + bdv + '\'' +
", sdv='" + sdv + '\'' +
", onOffValue='" + onOffValue + '\'' +
", analyser='" + analyser + '\'' +
'}';
}
}
if given the following input prints
Enter the following comma separated with a blank line to stop.
instrument name, Control Value, BDV, SDV, ON-OFF VALVE, Analyser
a,b,c,d,e,f
1,2,3,4,5,6
q,w,e,r,t,y
you entered
MyType{name='a', controlValue='b', bdv='c', sdv='d', onOffValue='e', analyser='f'}
MyType{name='1', controlValue='2', bdv='3', sdv='4', onOffValue='5', analyser='6'}
MyType{name='q', controlValue='w', bdv='e', sdv='r', onOffValue='t', analyser='y'}
You may need to use google guava multimap to achieve this.
A collection similar to a Map, but which may associate multiple values with a single key. If you call put(K, V) twice, with the same key but different values, the multimap contains mappings from the key to both values.
(or)
Change value as List and add all values which have same key to that list
Example:
List<String> valList = new ArrayList<String>();
valList.add(val1);
valList.add(val2);
mp.put(name, valList);
I would suggest looking at a Guava MultiMap
A collection similar to a Map, but which may associate multiple values
with a single key. If you call put(K, V) twice, with the same key but
different values, the multimap contains mappings from the key to both
values.
Otherwise you will have to implement a Map of Strings to some Java collection. That will work, but it's painful since you have to initialise the collection every time you enter a new key, and add to the collection if the empty collection exists for a key.
You may have a map of string array. Then you should retrive the array list and add new value.
Map<Object,ArrayList<String>> mp=new HashMap<Object, ArrayList<String>>();
I need to pass a 1d array that isn't defined in a method.
I need to create a testclass then make the arrays myself.
I'm just not sure about the syntax.
Example, here's my company class:
public class Company
{
String name;
String address;
Employee employeeList[] = new Employee[3];
public Company (String name, String address ,
Employee employeeList, String jobTitle )
{
this.name = name;
this.address = address;
}
public void printDetails()
{
for(int i = 0; i>employeeList.length;i++)
{
System.out.println(" The companys name is " + name);
System.out.println(" The Companys Address is "+ address);
System.out.println("The List of employees are " + employeeList[i].name);
System.out.println("The Titles of These Employees are " + employeeList[i].jobTitle);
}
}
}
But my testclass is where the problem lies.
Where do I go from here? Do do I put arrays(employees) into it?
public class TestCompany
{
public static void main(String[] args)
{ employees?
Company hungryBear = new Company("hungryBear ", "Those weird apartments ",////// );
}
}
public Company (String name, String address ,
Employee employeeList, String jobTitle )
Should be:
public Company (String name, String address ,
Employee []employeeList, String jobTitle )
Right now, you're not passing an array to your method, your passing an instance. You need to tell Java that you're passing an array.
Editted with new knowledge of the employee class...
Also, you will need to build the array in your main function before you pass it. Something like this:
public static void main(String[] args){
Employee [] employeeList = {
new Employee("Samuel T. Anders", "Player, Caprica Buccaneers"),
new Employee("William Adama", "Commander, Battlestar Galactica")
};
Company hungryBear = new Company("hungryBear ", "Those weird apartments ", employeeList);
}
Not really sure this answers your question, but maybe this will help you with the syntax of array passing a little.
Another edit, another way to initialize an array:
Empolyee [] employeeList = new Employee[2];
employeeList[0] = new Employee("Samuel T. Anders", "Player, Caprica Buccaneers");
employeeList[1] = new Employee("William Adama", "Commander, Battlestar Galactica");
Empolyee [] employeeList = new Employee[2];
for(int i=0;i<2;i++){
Scanner input = new Scanner(System.in);
employeeList[i] = input.next();
}