generating groups from txt file and generating them based on preferences - java

I am designing a group generator that takes in preferences such as “mix gender”, “mix nationality”... I am putting a list of student names, followed by nationality and gene set, in an arraylist. What is the easiest way to generate groups, based on user input, that each group consists of people from different nationalities, or balanced gender.
public ArrayList<String> readEachWord(String className)
{
ArrayList<String> readword = new ArrayList<String>();
Scanner sc2 = null;
try {
sc2 = new Scanner(new File(className + ".txt"));
} catch (FileNotFoundException e) {
System.out.println("error, didnt find file");
e.printStackTrace();
}
while (sc2.hasNextLine()) {
Scanner s2 = new Scanner(sc2.nextLine());
while (s2.hasNext()) {
String s = s2.next();
readword.add(s);
}
}
return readword;
}
I am using this to read a text file, and on each line, I have each student's name nationality and gender. I put them into an ArrayList and am right now trying to figure out how to evenly distribute them based on the user-desired group numbers.
I am using a txt file to store all the information since this group generator is customized for my school.

You can use the groupinBy method
basic tutorial
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Scratch {
public static void main(String[] args) {
String student1 = "Macie American Female";
String student2 = "Yago Brazilian Male";
String student3 = "Tom American Male";
List<String> students = Arrays.asList(student1, student2, student3);
System.out.println(groupByGender(students));
System.out.println(groupByNationality(students));
}
private static Map<String, List<Student>> groupByNationality(List<String> students) {
return students.stream().map(s -> mapToStudent(s)).collect(Collectors.groupingBy(Student::getNationality));
}
private static Map<String, List<Student>> groupByGender(List<String> students) {
return students.stream().map(s -> mapToStudent(s)).collect(Collectors.groupingBy(Student::getGender));
}
private static Student mapToStudent(String s) {
String[] ss = s.split(" ");
Student student = new Student();
student.setName(ss[0]);
student.setNationality(ss[1]);
student.setGender(ss[2]);
return student;
}
private static class Student {
String name;
String nationality;
String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", nationality='" + nationality + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
}

First of all, it would be better if you put your while loop inside the try block because you don't want to get there if the file hasn't been found.
Second, you don't need to create a new instance of Scanner just to read every line. You can simply read your file word by word:
while (sc2.hasNext())
readword.add(sc2.next());
To group the students according to their nationality, you can do something like that:
String nationality = [UserInput] ;
List<String> group = new ArrayList<>();
for (int i = 0; i < readword.size(); i++)
if (readword.get(i + 1).equals(nationality)
group.add(readword.get(i));

Related

How to remove an object from an ArrayList<Class>?

I'm trying to remove the object from an ArrayList of
type Contact class. I am trying to take input from users and want to
delete that object from ArrayList
public class Contacts {
private String name, phoneNumber;
public Contacts(){
}
public Contacts(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
#Override
public String toString() {
return "Contacts{" +
"name='" + name + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
'}';
}
public static Contacts createContact(String name, String phoneNumber) {
return new Contacts(name, phoneNumber);
}
}
Here I tried to add objects with names and numbers and then print them and I want to delete a particular object.
public class Mobile {
ArrayList<Contacts> mycontacts;
public Mobile() {
this.mycontacts = new ArrayList<Contacts>();
}
public void addContacts() {
System.out.println("enter contact name");
Scanner sc = new Scanner(System.in);
String name = sc.nextLine();
System.out.println("enter contact number");
String number = sc.nextLine();
Contacts contacts = new Contacts(name, number);
mycontacts.add(contacts);
}
public void print() {
for (Contacts contacts : mycontacts) {
System.out.println(contacts.getName() + "->" + contacts.getPhoneNumber());
}
}
public String findcontact() {
Scanner scanner = new Scanner(System.in);
System.out.println("enter contact name");
String name = scanner.nextLine();
System.out.println("enter phone number");
String number = scanner.nextLine();
Contacts contacts = new Contacts(name, number);
int x = mycontacts.indexOf(contacts);
return mycontacts.get(x).getName();
}
public void remove() {
Scanner scanner = new Scanner(System.in);
System.out.println("enter contact name");
String name = scanner.nextLine();
System.out.println("enter contact number");
String number = scanner.nextLine();
Contacts contacts = new Contacts(name, number);
Iterator<Contacts> itr = mycontacts.iterator();
while (itr.hasNext()){
Contacts contacts1 = itr.next();
System.out.println(contacts1);
if (contacts1==contacts){
itr.remove();
}
}
}
}
You need to implement the equals method on your Contacts class, something like this
public boolean equals(Object other){
if(other instanceof Contract){
Contract otherC = (Contract)other;
return this.name.equals(otherC.name) && this.phoneNumber.equals(otherC.phoneNumber);
}
return false;
}
Java isn't my strong suit, but I think you can fix it like this:
Iterator<Contacts> itr = mycontacts.iterator();
while (itr.hasNext()){
Contacts contacts1 = itr.next();
System.out.println(contacts1);
if (contacts1.getName()==contacts.getName() && contacts1.getPhoneNumber() == contacts.getPhoneNumber()){
itr.remove();
}
}
Or simplified:
mycontacts.removeIf(i -> i.getName()==contacts.getName() && i.getPhoneNumber()==contacts.getPhoneNumber());
I think what is happening is that in this comparison: if (contacts1==contacts)
These will never be equal, as they are different objects, but they have the same values for their class variables.
https://www.baeldung.com/java-comparing-objects
the value of those objects is not 1. Rather it is their memory addresses in the stack that are different since both objects were created using the new operator.
edit: actually, another answer showed up while I was answering, which is better. I'll leave mine up since I think I gave more explanation.
There are two ways to remove an element from an ArrayList:
remove(Object object)
remove(int index)
So if you're using the name as the key, it could look something like:
public void removeContact(String name) {
for(contact : mycontacts) {
if(contact.name == name) {
mycontacts.remove(contact)
}
}
}
I tried using the following code, it worked. Thank you all who helped me. :)
for (Contacts mycontact : mycontacts) {
if (mycontact.getName().equals(name)) {
System.out.println("removed contact"+mycontact.getName()+"->"+mycontact.getPhoneNumber());
mycontacts.remove(mycontact);
}
else{
System.out.println("error deleting contact");
}
}

How can we create an instance for a nested class in array of objects in java?

import java.util.Arrays;
import java.util.Scanner;
public class employee{
public String name;
public class employee_address{
String street_name;
String city;
String zipcode;
String state;
String country;
}
public static void main(String []args){
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt();
employee[] employees_list = new employee[no_of_employees];
for(int i = 0;i < no_of_employees;i++){
employees_list[i].name = user_input.nextLine();
employees_list[I].employee_address = // this is it ?
}
}
}
In the code above I do understand that the employee_address is a class and can't be accessed
directly without an instance being created like in the code, that makes no sense. but how can I create an instance of the employee_address class that is associate with each employee.
like in the code above 'employee_address' is associated with every employee but how can the class 'employee_address' be initialised and how can I set the street_name, city and the rest of the members in the address class. any ideas would be appreciated.
You can't directly create an instance of inner class, the reason because since it is the property of another instance we always need to use it though the instance of parent variable.
Let's say you have a class, which have two propeties:
public class Employee {
public String name;
public EmployeeAddress emAddress;
}
to access emAddress you need to use through the instance of Employee class, for example -
Employee object = new Employee();
EmployeeAddress empAdd = object.new EmployeeAddress();
Full code:
public class Employee {
public String name;
public EmployeeAddress emAddress;
public class EmployeeAddress {
String street_name;
String city;
String zipcode;
String state;
String country;
public String getStreet_name() {
return street_name;
}
public void setStreet_name(String street_name) {
this.street_name = street_name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString() {
return "EmployeeAddress [street_name=" + street_name + ", city=" + city + ", zipcode=" + zipcode
+ ", state=" + state + ", country=" + country + "]";
}
}
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int no_of_employees = user_input.nextInt(); // let's say no_of_employees = 1
Employee[] employees = new Employee[no_of_employees];
for (int i = 0; i < no_of_employees; i++) {
Employee object = new Employee();
object.setName("Virat Kohli");
EmployeeAddress empAdd = object.new EmployeeAddress();
empAdd.setCity("New Delhi");
empAdd.setCountry("India");
empAdd.setState("Delhi");
empAdd.setStreet_name("Chandni Chalk");
empAdd.setZipcode("741124");
object.setEmAddress(emAddress);
employees[i] = object;
}
System.out.println(employees[0]);
user_input.close();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmployeeAddress getEmAddress() {
return emAddress;
}
#Override
public String toString() {
return "Employee [name=" + name + ", emAddress=" + emAddress + "]";
}
public void setEmAddress(EmployeeAddress emAddress) {
this.emAddress = emAddress;
}
}
I have modified your code to sonar standard.
Below code uses Java naming conventions (which your code does not).
Notes after the code.
import java.util.Scanner;
public class Employee {
private String name;
private EmployeeAddress address;
public class EmployeeAddress {
String streetName;
String city;
String zipcode;
String state;
String country;
}
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
int noOfEmployees = userInput.nextInt();
Employee[] employeesList = new Employee[noOfEmployees];
for (int i = 0; i < noOfEmployees; i++) {
employeesList[i] = new Employee();
employeesList[i].name = userInput.nextLine();
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
employeesList[i].address = employeeAddress;
employeesList[i].address.streetName = userInput.nextLine();
}
}
}
An inner class is a normal class. It is not a member of its enclosing class. If you want class Employee to have an [employee] address, as well as a [employee] name, you need to add another member variable to class Employee whose type is EmployeeAdress.
Employee[] employeesList = new Employee[noOfEmployees];
The above line creates an array but every element in the array is null. Hence you need to first create a Employee object and assign it to an element of the array. Hence the following line in my code, above:
employeesList[i] = new Employee();
Since EmployeeAddress is not a static class, in order to create a new instance, you first need an instance of the enclosing class, i.e. Employee. Hence the following line in the above code.
EmployeeAddress employeeAddress = employeesList[i].new EmployeeAddress();
Since all your code is in class Employee, in method main you can directly access the members of both class Employee and EmployeeAddress. Nonetheless you need to be aware of the different access modifiers in java.
A few hints:
stick to naming conventions: class names in Java start with capital letters
use (class) definitions before using them (collect them at the top if not inconventient)
if you are sure you want to use inner classes, set them static, unless you want them to be entangled in generics.
Usually normal classes in each their own file are a lot more flexible and far easier to use
if you use objects that only carry public data, try to use final keyword and initialize them ASAP
use proper objects first, and after finishing them assign them to arrays. avan better would be the use of ArrayList and the like
if Employee contains EmployeeAddress, it should initialize it if conventient. so an object is always responsible for its own stuff
Use try/resrouce/catch
scanner.nextInt() can be problematic with newline/line breaks. For user input better readLine() and parse input
Code:
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;
public class Employee {
static public class EmployeeAddress {
public final String street_name;
public final String city;
public final String zipcode;
public final String state;
public final String country;
public EmployeeAddress(final Scanner pScanner, final PrintStream pOutPS) {
street_name = readLine(pScanner, pOutPS, "Please enter Street Name:");
city = readLine(pScanner, pOutPS, "Please enter City Name:");
zipcode = readLine(pScanner, pOutPS, "Please enter Zip Code:");
state = readLine(pScanner, pOutPS, "Please enter State:");
country = readLine(pScanner, pOutPS, "Please enter Country:");
}
}
static public String readLine(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
pOutPS.print(pPrompt);
final String value = pScanner.nextLine();
pOutPS.println();
return value;
}
static public int readInt(final Scanner pScanner, final PrintStream pOutPS, final String pPrompt) {
return Integer.parseInt(readLine(pScanner, pOutPS, pPrompt));
}
public final String name;
public final EmployeeAddress address;
public Employee(final Scanner pScanner, final PrintStream pOutPS) {
name = readLine(pScanner, pOutPS, "Please enter Employee Name: ");
System.out.println("Name: " + name);
address = new EmployeeAddress(pScanner, pOutPS);
}
public static void main(final String[] args) {
try (final Scanner user_input = new Scanner(System.in);
final PrintStream output = System.out;) {
final int no_of_employees = readInt(user_input, output, "Please enter number of users: ");
final Employee[] employees_list = new Employee[no_of_employees]; // either this line
final ArrayList<Employee> employees = new ArrayList<>(); // or this line
for (int i = 0; i < no_of_employees; i++) {
output.println("Creating user #" + (i + 1) + "...");
final Employee newEmployeeWithAddress = new Employee(user_input, output);
employees_list[i] = newEmployeeWithAddress; // either this line
employees.add(newEmployeeWithAddress); // or this line
}
}
}
}

How to print an ArrayList? - java

Question will be below.
public class University {
ArrayList<Student> students;
public University() {
students = new ArrayList<Student>();
}
public void addStudent(Student students) {
this.students.add(students);
}}
public class Student {
String name;
String studentID;
static int studentNumber = 0;
Student(String name, String sID){
this.name = name;
this.studentID = sID;
studentNumber++;
}}
public class TestUniversity {
public static void main(String[] args) {
University universityRegister = new University();
Student studentRegister = new Student("Rachel Green", "a1234");
universityRegister.addStudent(studentRegister);
studentRegister = new Student("Monica Geller", "a12345");
universityRegister.addStudent(studentRegister);
studentRegister = new Student("Ross Geller", "a1111");
universityRegister.addStudent(studentRegister);
System.out.println("Number of student in University: " + Student.studentNumber);
}}
A. I created 3 classes, 1.Student, 2.University, 3.UniversityTester, in 3 different files.
B. I created 3 objects of type Studnet, and stored them in the University class as an ArrayList.
I would like to know how I can print the ArrayList of the students including all information from the UniversityTester class? In the future, I will create another object called Stuff and I will store it in the University class as an ArrayList stuffList. Therefore, I don't want to print the students list from class Student.
Override toString() method in Student class as follows:
import java.util.StringJoiner;
public class Student {
String name;
String studentID;
static int studentNumber = 0;
Student(String name, String sID) {
this.name = name;
this.studentID = sID;
studentNumber++;
}
#Override
public String toString() {
return new StringJoiner(", ", Student.class.getSimpleName() + "[", "]")
.add("name='" + name + "'")
.add("studentID='" + studentID + "'")
.toString();
}
}
Now you can print the array list as follows in TestUniversity:
System.out.println("Student Details: " + universityRegister.students);
Add this to your student class:
#Override
public String toString() {
return String.format("Student: %s , StudentID: %s", name, studentID);
}
And then you can print the entire array like this:
System.out.println("Students: " universityRegister.students);
//Or like this:
for(Student st: universityRegister.students){
System.out.println(st);
}

How to read a file containing strings and integers into an ArrayList and sort by integer?

I'm trying to read from a text file containing a list of names and grades, organized by line, i.e.:
David Smith 84
Susan L Potter 100
...
Then store them (by line) in an ArrayList, and sort that ArrayList by the students' grade using a selection sort algorithm, however I've tried multiple different ways to code this and every edit seems to prompt another error (I'm extremely new to programming). This is what I currently have:
import java.io.*;
import java.util.*;
public class Grades {
private static void sort(ArrayList<String> list) {
int pFill;
int pTest;
int pSmallest;
String temp;
for (pFill = 0; pFill < list.size(); pFill++) {
pSmallest = pFill;
for (pTest = pFill + 1; pTest < list.size(); pTest++) {
if (pTest < pSmallest) {
pSmallest = pTest;
}
}
temp = list.get(pSmallest);
list.set(pSmallest, list.get(pFill));
list.set(pFill, temp);
}
}
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
String fileName = "students.txt";
try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
while(input.ready()){
list.add(input.readLine());
}
input.close();
sort(list);
System.out.println(list);
} catch (IOException e){
System.out.println(e.getMessage());
}
}
}
You can create a student object to hold name and grade separately. Once you have added all the data into list you can directly use list.sort() method by using Comparator but in your case you want to write selection sort that's why you have to write another method to do selection sort.
package com.stackovflow.problems;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Grades {
public static void main(String[] args){
ArrayList<Student> list = new ArrayList<>();
String fileName = "students.txt";
try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
while(input.ready()){
String line = input.readLine().trim();
String name = line.substring(0,line.lastIndexOf(' '));
int grade = Integer.parseInt(line.substring(line.lastIndexOf(' ')+1));
list.add(new Student(name, grade));
}
input.close();
selectionSort(list);
System.out.println(list);
} catch (IOException e){
System.out.println(e.getMessage());
}
}
private static void selectionSort(ArrayList<Student> list) {
int pFill;
int pTest;
int pSmallest;
Student temp;
for (pFill = 0; pFill < list.size(); pFill++) {
pSmallest = pFill;
for (pTest = pFill + 1; pTest < list.size(); pTest++) {
Student pTestStudent = list.get(pTest);
Student pSmallestStudent = list.get(pSmallest);
if (pTestStudent.getGrade() < pSmallestStudent.getGrade()) {
pSmallest = pTest;
}
}
if(pSmallest!=pFill) {
temp = list.get(pSmallest);
list.set(pSmallest, list.get(pFill));
list.set(pFill, temp);
}
}
}
}
//This class is to hold line data in your students.txt file
class Student{
private String name;
private int grade;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public Student(String name, int grade) {
super();
this.name = name;
this.grade = grade;
}
#Override
public String toString() {
return "Student [name=" + name + ", grade=" + grade + "]";
}
}
It will be easy if you declare a Student class with 2 fields name and age. And you can make the Student class implement Comparable and compare on the basis of grade. It will look something like this:
public class Student implements Comparable<Student> {
private final String name;
private final int grade;
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
#Override
public int compareTo(Student s) {
return Integer.compare(this.grade, grade);
}
}
To populate the Student object you will need to split the String and extract the name and grade, and then call new Student(name, grade).
In your sort method you can pass a List<Student> where you can compare 2 students (as Student implements Comparable<Student>) by calling something like s1.compareTo(s2).
Once you got the list of student. You can use Comparator to do this.
List<Student> sorted=list.sort(Comparator.comparing(p-> p.getGrade()));
Or use stream api
List<Person> result =list.stream().sorted((p1, p2)>p1.getGrade().compareTo(p2.getGrade())).collect(Collectors.toList());
Create a separate Student.java file in the same folder to hold the Student class:
public class Student {
private final String name;
private final int grade;
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
public String getName(){
return name;
}
public int getGrade(){
return grade;
}
}
Then split each line by space and set the first tokens as the name and the last as the grade, then use Comparator to sort the ArrayList of Student Objects:
import java.io.*;
import java.util.*;
public class Grades {
private static ArrayList<Student> sort(ArrayList<String> list) {
ArrayList<Student> students = new ArrayList<Student>();
String name = "";
int grade;
for (String line : list) {
String[] splitted = line.split("\\s+");
for(int i = 0;i< splitted.length-1;i++){
name += splitted[i] + " ";
}
grade = Integer.parseInt(splitted[splitted.length-1]);
students.add(new Student(name,grade));
name = "";
}
students.sort(Comparator.comparing(student-> student.getGrade()));
return students;
}
public static void main(String[] args){
ArrayList<String> list = new ArrayList<>();
String fileName = "students.txt";
try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
while(input.ready()){
list.add(input.readLine());
}
input.close();
ArrayList<Student> sortedStudents = sort(list);
for (Student currentStudent : sortedStudents)
System.out.println(currentStudent.getName() + currentStudent.getGrade());
} catch (IOException e){
System.out.println(e.getMessage());
}
}
}

Simple program for making shifts

My dad asked me to make a program for him that will randomly take a name, surname etc. from Excel (or CSV file) and assign employees to the work. Each person must be at work minimum once and maximum 4 times a month. Program output should look like this:
Day 1: John Smith, James Smith Day 2: Charlie Smith, Thomas Smith
And this is how my code looks like right now
public static void main(String[] args) {
String FileName = "excel.csv";
File f = new File(FileName);
String read = "";
Map<Integer, Surname>SurnameArray = new HashMap<Integer, Surname>();
try {
Scanner scanner = new Scanner(f);
while(scanner.hasNextLine()) {
read = scanner.nextLine();
String[] arraySplit = read.split(",");
int kod = Integer.parseInt(tablicaSplit[0]);
String rank = tablicaSplit[1];
String name = tablicaSplit[2];
String surname = tablicaSplit[3];
SurnameArray.put(kod, new Nazwiska(kod, rank, name, surname));
SurnameArray.get(kod).getAll();
}
} catch (FileNotFoundException e) {
System.out.println("No file!");
}
}
}
And the second class looks like this:
Class Surnames {
private int kod;
private String rank;
private String name;
private String surname;
public Surnames(int kod, String rank, String name, String surname) {
super();
this.kod = kod;
this.rank = rank;
this.name = name;
this.surname = surname;
}
public void getAll() {
System.out.println(rank + " " + name + " " + surname);
}
public int getKod() {
return kod;
}
public void setKod(int kod) {
this.kod = kod;
}
public String getRank() {
return rank;
}
public void setRank(String rank) {
this.rank = rank;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setNazwisko(String surname) {
this.surname = surname;
}
}
I'm stuck at this moment. I think that this code is more complicated than it should be. If someone could show me how can i make it or maybe there is simpler way to make something like this.
I would do it this way:
class Surnames{
private final HashSet<String> EMPLOYEES;
private ArrayList<String> positions;
Surnames(String csv){
HashSet<String> tempEMPLOYEES = new HashSet<>();
ArrayList<String> tempPositions = new ArrayList<>();
/*here the code for putting csv data ino an tempEMPLOYEE hashSet, or a static setter method doing this, as well for tempPositions, containing array list of positions remember to check
if the hashset's size is equal or lower than arrayList's*/
EMPLOYEES = tempEMPLOYEES;
positions = tempPosition;
}
public void printShift(){
for(int i = 0; i < EMPLOYEES.size(); i++){
System.out.println(positions.get(i) + "- " + EMPLOYEES.get(i));
}
}
}
Since hashSet gives different object position in the set every single run of the program, placing EMPLOYEES to positions will be random. I mentioned checking that HashSet EMPLOYEES should be less size than positions. I iterate on the hashset- every employee should get a position.

Categories

Resources