Sorting an array list with a delimiter - java

I have been stuck on this problem for so long and i have no idea what to do.
Basically i have a text file with people names then student number then prize money like this:
Green%3243%1000
Kevin%7657%400
Frank%345%10000
Bob%5435%5000
Stefan%31231%1000
Javis%4532%100
IronMan%5435%2000
Lamp%534%3000
What i want to be able to do is sort the array based on the last number.
I tried this abomination (Don't bother reading it its garbage):
boolean flag = true;
String temp;
int temp1;
int temp2;
while (flag){
flag = false;
for(int j=0; j < list.size() -1; j++ ){
System.out.println(list.get(j));
Scanner s = new Scanner(list.get(j)).useDelimiter("%");
s.next();
s.next();
temp1 = s.nextInt();
Scanner s2 = new Scanner(list.get(j+1)).useDelimiter("%");
s2.next();
s2.next();
temp2 = s2.nextInt();
if (temp1 < temp2){
temp = list.get(j);
list.add(j, list.get(j+1));
list.add(j+1,temp);
flag = true;
}
}
}
But its just infinitely looping. My though while making it was just patching array lists into a bubble sort.
If anyone has any ideas and is willing to share them it will be greatly appreciated.

Java is an object-oriented language, so I'll just use objects:
Create a Student object with the three values you want to store (and a toString() method to print them separated by "%":
public class Student {
private final String name;
private final int number;
private final int prizeMoney;
public Student(final String name, final int number, final int prizeMoney) {
this.name = name;
this.number = number;
this.prizeMoney = prizeMoney;
}
#Override
public String toString() {
return name+"%"+number+"%"+prizeMoney;
}
public int getPrizeMoney() {
return prizeMoney;
}
}
Read your lines as Student objects, and store them in a List:
final Scanner scan = new Scanner(new File("/path/to/StudentsList"));
final List<Student> students = new ArrayList<Student>();
while (scan.hasNextLine()) {
final Scanner line = new Scanner(scan.nextLine());
line.useDelimiter("%");
students.add(new Student(line.next(), line.nextInt(), line.nextInt()));
line.close();
}
scan.close();
Order the List with a custom Comparator, and print it:
students.sort(new Comparator<Student>() {
#Override
public int compare(final Student s1, final Student s2) {
return s1.getPrizeMoney()-s2.getPrizeMoney();
}
});
for (final Student student: students)
System.out.println(student);
Output:
Javis%4532%100
Kevin%7657%400
Green%3243%1000
Stefan%31231%1000
IronMan%5435%2000
Lamp%534%3000
Bob%5435%5000
Frank%345%10000

Here's something for you to get head started.
Create a map for prize money => line as key/value pair
Read each line in the file, parse it and put key/value pair in the above map
Once your map is ready, convert the keys entry set into the collections like list
Sort the collections, using Collections.sort()
Iterate over the created map, and for each value in the collection get the corresponding value from the map.
Hope this helps you to get the workflow.

Id consider creating a 3d array here 8x8x8 from right to left in the array is row, col, and in so [0][0][1] is block one or kevin [0][1][1] is 7657 [1][1][1] is 400. I like this way because not only does it give each 'item' an array it allows you to keep it organized and easily accessable

Related

Adding more variables to an array of objects in java

I've made a bit of a mess on a project of mine. I have to create an array of objects. I have made an array but it only has 1 field 'myMonths' referring to the length of time of the project.
In my main method:
case 1:
int n = 1; //int n = number of projects
Scanner sc = new Scanner(System.in);
//myMonths = new int[amount];
System.out.println("** Only projects with a duration between 2 and 12 months can be included **");
System.out.println("What was the duration of your projects in months?");
for(int i=0; i<1; i++){
int a = sc.nextInt();
//display error message
if((a < 2) || (a > 12)){
System.out.println(" Please enter an amount between 2 and 12 months. ");
}
//add to the array
else{
myMonths[index++] = a;
}
}
calc.setMyMonths(myMonths); //creating the object
break;
In my class on separate file:
public class MenuTestClass{
private int myMonths[];
private double average; //store average value of numbers
private boolean averageCanBeCalculated;
private int max; // store max number from array. to be calculated
public MenuTestClass(){
myMonths = new int[5];
}
public MenuTestClass(int[] myMonths){
this.myMonths = myMonths;
}
public void setMyMonths(int[] values){ //declare setter method
myMonths = values;
}
I should have added in two more fields, both strings. Is there a way I can add more fields/attributes to this array and have them viewable at the same time under 1 index? For example at [0] projectName, projectManager, myMonths ie(string, string, integer).
Any advice would be great, I am getting really confused with OOP. Thanks in advance!
Yes, create a class containing your three properties:
class MyContainer {
public MyContainer(int durationMonths, String projectName, String projectManager) {
this.durationMonths = durationMonths;
this.projectName = projectName;
this.projetManager = projectManager;
}
public int durationMonths;
public String projectName;
public String projectManager;
}
Then create an array of this class with:
MyContainer[] myArray = new MyContainer[numberOfProjects];
Add items to the array like this:
myArray[0] = new MyContainer(3, "super project", "awesome manager");

Java Array TopCustomers

I'm currently trying to working through a problem with ArrayList.
This is supposed to take the input of the user and customers sales and display the top customer. Yet, I'm having and issue with an inner while.
Using VSCODE. The inner while is throwing an error within the inner if sales.get(j) > largest) stating the > is undefined.
Please, any help would be greatly appreciated.
import java.util.ArrayList;
import java.util.Scanner;
public class TopCusomters {
public static void main(String[] args)
{
ArrayList sales = new ArrayList();
ArrayList customers = new ArrayList();
int numOfItems = 0;
double price = 0;
Scanner in = new Scanner(System.in);
boolean entryComplete = false;
do {
System.println("Customers Names");
customers.add(in.next());
System.println("Sales of the Customer (0 to end):");
price = in.nextDouble();
sales.add(price);
numOfItems++;
}while(price != 0 && mumOfItems < 100);
System.out.println("Please provide values of N");
int topN = in.nextInt();
ArrayList topCustomers = nameOfBestCustomers(sales, customers, topN);
System.out.println(" Top Customers list" + "is" + topCustomers.toString());
}
public static ArrayList nameOfBestCustomers (ArrayList sales,ArrayList customers, int topN)
{
ArrayList bestCustomers = new ArrayList();
sortCustomers(sales,customers);
int i = 0;
while (i)
{
bestCustomers.add(customers.get(i));
i++;
}
return bestCustomers;
}
public static void sortCustomers(ArrayList sales, ArrayList customers)
{
int i = 0;
double temp = 0;
String tempName = "";
while (i)
{
double largest = sales.get(i);
int largestIndex = i;
int j = i;
while (j)
{
if(sales.get(j) > largest)
{
largest = sales.get(j);
largestIndex = j;
}
i++;
}
temp = sales.get(i);
sales.set(i,sales.get(largestIndex));
sales.set(largestIndex,temp);
tempName = customers.get(i);
customers.set(i,customers.get(largestIndex));
customers.set(largestIndex, tempName);
i++;
}
}
}
You are not specifying object types that lists are holding for below declarations ,
ArrayList sales = new ArrayList();
ArrayList customers = new ArrayList();
So when you retrieve objects from list and try to apply operators, Java doesn't know which type its working on. ( Java assumes java.lang.Object and operator > doesn't make sense on Object )
For long term solution , declarations should be changed as below or you can try that after explicit cast too,
List<Double> sales = new ArrayList<>();
List<String> customers = new ArrayList<>();
where Double is java.lang.Double
ArrayList without type will default to ArrayList<Object>, that means that sales.get(j)'s return value is Object. You probably want ArrayList<Double>.
You have multiple syntax errors, for example:
Conditional expression like while (<expr>) { ... } need to evaluate to boolean. while(i) is not a valid expression, see
The while and do-while Statements docs.
do { ... } is not a valid Java construct, most likely you tried to use a do-while loop do { ... } while (<expr>); loop.
You are using rawtype ArrayList. Most likely it should be List<Double>. You need generics to compare sales elements with double largest using auto-boxing, see Lesson: Generics (Updated) docs.

Method to get an array of inputs in Java

I have to do an assignment for school that is basically a small online shop with 10 items.
The way I've done it is with having 2 premade arrays that include the price, and product names. Then I made an array for storing user inputs and an array for storing the multiplied result of input by price. The program works, however the problem is we needed to have a separate file that will contain the item and price list and then call it by using a separate method.
I've been trying to figure out a way to do it but it's a bit above my head to be honest and I'm running out of time. If anyone can advise me how I could separate my functions and product/price lists using methods it would be much appreciated.
This is my program
import java.util.Scanner;
public class dunnes{
public static void main(String args[]){
Scanner in = new Scanner(System.in);
String product[]={"Coat", "Jeans", "Shirt", "Shoes", "Skirt", "Dress", "Socks","Scarf", "Handbag","Vest"};
double price[]={99.99, 53.59, 9.99, 29.99, 24.99, 83.16, 5.99, 10.95, 23.99, 18.99};
int howMany[]=new int[10];
double multiplied[]=new double[10];
int i =0;
boolean err = false;
boolean flag = true;
for(i = 0; i<price.length; i++){
System.out.print(+i+1+ " Please enter how many ");
System.out.print(product[i]+ " you would like to buy (");
System.out.print(price[i]+ ") euro each \n");
do{
err = false;
try{
howMany[i] = Integer.parseInt(in.next());
}catch (Exception e){
err = true;
System.out.print("Incorrect input. Must be whole numbers. \n");
System.out.print(+i+1+ " Please enter how many ");
System.out.print(product[i]+ " you would like to buy (");
System.out.print(price[i]+ ") euro each \n");
}
}while(err);
}
for(i = 0; i<price.length; i++){
multiplied[i]=howMany[i]*price[i];
multiplied[i] = Math.round(multiplied[i] * 100.0) / 100.0;
}
System.out.print("\nUnsorted total bill:\n\n");
for(i = 0; i<price.length; i++){
System.out.print(product[i]+"\t\t");
System.out.print(""+multiplied[i]+"\n");}
while(flag){
flag=false;
for(i=0;i<multiplied.length-1;i++){
if(multiplied[i]>multiplied[i+1]){
double temp = multiplied[i];
multiplied[i] = multiplied[i+1];
multiplied[i+1]= temp;
String temp2=product[i];
product[i]=product[i+1];
product[i+1]=temp2;
flag = true;
}
}
}
System.out.print("\nSorted total bill:\n\n");
for(i = 0; i<price.length; i++){
System.out.print(product[i]+"\t\t");
System.out.print(""+multiplied[i]+"\n");
}
}
}
So, first instead of using multiple arrays of primitives, use one java.util.List of Java objects. You can have a Java class called Product with the fields name and price and getters and setters and then create one Product instance for each of your products and put them in the list. It's doesn't seems like much now, but you'll see this will make making changes to your code much more easier. Like this:
public class Product {
private String name;
private Integer price;
public Product(String name, Integer price) {
this.name = name;
this.price = price;
}
public String getName() {return name;}
public Integer getPrice() {return price;}
public void setName(String name) {this.name = name;}
public void setPrice(Integer price) {this.price = price;}
}
Now on the big part, as I understand you have to load the product list from a file, it's suggest using a properties files to do that, it's a file with on each line a key, the equals sign and a value, and there is already utilities on Java to parse those files, java.util.Properties. There are not exactly designed for this kind of job, but if you are short on time and you don't know how to create a parser yourself, this might be your best solution. You can do something like:
Properties prop = new Properties();
try (InputStream stream = new FileInputStream("path/filename")) {
prop.load(stream);
} finally {
stream.close();
}
List<Product> products = new ArrayList<>();
for(Object key : prop.keySet()) {
String name = (String) key;
Integer price = Integer.valueOf((String) prop.getProperty(key));
products.add(new Product(name, price));
}

Iterating over two arrays simultaneously using for each loop in Java

Student's names(String[]) and corresponding marks(int[]) are stored in different arrays.
How may I iterate over both arrays together using for each loop in Java ?
void list() {
for(String s:studentNames) {
System.out.println(s); //I want to print from marks[] alongside.
}
}
One trivial way could be using index variable in the same loop. Is there a good way to do?
You need to do it using the regular for loop with an index, like this:
if (marks.length != studentNames.length) {
... // Something is wrong!
}
// This assumes that studentNames and marks have identical lengths
for (int i = 0 ; i != marks.length ; i++) {
System.out.println(studentNames[i]);
System.out.println(marks[i]);
}
A better approach would be using a class to store a student along with his/her marks, like this:
class StudentMark {
private String name;
private int mark;
public StudentMark(String n, int m) {name=n; mark=m; }
public String getName() {return name;}
public int getMark() {return mark;}
}
for (StudentMark sm : arrayOfStudentsAndTheirMarks) {
System.out.println(sm.getName());
System.out.println(sm.getMark());
}
The underlying problem is actually that you should tie both of the arrays together and iterate across just one array.
Here is a VERY simplistic demonstration - you should use getters and setters and you should also use a List instead of an array but this demonstrates the point:
class Student {
String name;
int mark;
}
Student[] students = new Student[10];
for (Student s : students) {
...
}
If them both have the same size, I would write:
for(int i = 0; i<marks.length; i++) {
String names= studentNames[i]
int mark = marks[i];
}
The other way is to use a verbose for loop statement such as;
int i,j;
for(i = 0, j=0; i<= student.length-1 && j <=grades.length-1; i++,j++)
{
...
}

How to sort three arrays in java?

I have three arrays in my proggramme Surname, Forename and result and need to create a sort array
Surname: Chris Forename: Charleton: Result: 54
Surname: Annett: forename: Lyle: result 67
If I wanted to sort it by alphabetical of last name, i need all the fields to move, instead of just the surname. This is the bubble sort code i'm working off
int swap;
boolean swapflag = true;
//outer loop
while (swapflag == true)
{
swapflag = false;
//inner loop
for (int index=0; index < (nums.length - 1); index++)
{
//swap routine
if (nums[index]> nums[index + 1])
{ //swap routine
swap = nums[index];
nums[index] = nums[index + 1];
nums[index + 1] = swap;
swapflag = true;
}
}//end inner
}//end outer
System.out.println ("\nArray Contents after sorting"
+ "\n*************");
for (int index=0; index < nums.length; index ++)
{
System.out.println("Array element "
+ index + ": " + nums[index]);
}
}
}
` package projStudent;
import java.util.Scanner;
public class UnitResults
{
//delcare Scanner as keyb
static Scanner keyb = new Scanner (System.in);
//declare fields
static String studentForename [];
static String studentSurname [];
static int [] studentResult;
static int pointer;
//constructor
UnitResults(int sizeofclass)
{//start of constructor
studentForename = new String [sizeofclass];
studentSurname = new String [sizeofclass];
studentResult = new int [sizeofclass];
pointer = 0;
}//end of constructor
public boolean add(String studentForename[], String studentSurname[],
int studentResult[])
{//start of add method
if (pointer == studentResult.length )
{//start of if statement
System.out.println("Sorry Array is full");
return false;
studentResult[pointer] = studentResult[];
pointer ++;
}//end of if statement
}//end of add method
public boolean delete(int element)
{//start of delete method
element = element - 1;
if ((element >= 0) && ( element < pointer))
{//start of if statement
for(int index = (element + 1); index < pointer; index++)
{//start of for statement
studentResult[index - 1] = studentResult[index];
}//end of for statement
pointer--;
return true;
}//end of if statement
else
{//start of else statement
return false;
}//end of else statement
}//end of delete method
public String find()
{//start of display
String strOutput="";
strOutput = strOutput + "Students";
if (pointer==0)
{//start of if statement
strOutput = strOutput + "There are no records in this Array";
return strOutput;
}//end of if statement
for (int index=0; index < pointer; index++)
{//start of for method
strOutput = strOutput + "Student Name" + studentSurname[index] + studentForename +
"Student Result" + studentResult +"\n";
}//end of for method
return strOutput;
}//display
public int sort (int UnitResults)
{//start of sort
int sort;
boolean swapflag = true;
while (swapflag == true)
{//start of while loop
swapflag = false;
for (int index=0; index < (UnitResults - 1); index++)
{
if (studentResult[index]> studentResult[index + 1])
{ //swap routine
sort = studentResult[index];
studentResult[index] = studentResult[index + 1];
studentResult[index + 1] = sort;
swapflag = true;
}
}
}//end of while loop
}//end of sort
}`
Unfortunately, your post is confusing as you don't include some things, like just what is the current array you are sorting. Still, if I understand your question correctly...
Regardless of the language, your strategy would involve changes to how you swap the elements. If your array consists of composite data, then simply assigning in a swap is fine. If your data is scattered, then your swap needs to swap each variable. You can always just sort the indices of the array into another array, then use that array to indirectly reference the first, for sorted access.
I would suggest you use an List for this purpose.
First create an object. For example "Person" containing members for "Forname","Surename","Result". Then fill the list with these objects, implement the Interface Compareable and use the Collection.sort() methode.
class Person implements Comparable<Person>
{
private String forname;
private String surname;
private int rating;
public Person(String forename, String surname, int rating)
{
this.forname = forename;
this.surname = surname;
this.rating = rating
}
public int compareTo(Person p) {
if(p.rating == this.rating)
return 0;
else if(p.rating < this.rating)
return -1;
return 1;
}
}
class Test{
public static void main(String[] args){
List<Person> personList = new ArrayList<Person>();
Person p1 = new Person("John","Smith",10);
Person p2 = new Person("Max","Muster",20);
Person p3 = new Person("Sarah","Clark",15);
personList.add(p1);
personList.add(p2);
personList.add(p3);
personList.sort();
}
}
There are a number of features of the Java programming languages that can help you resolve the problem that you are having, the first of which is inclusion of appropriate data structures and methods with which to manipulate objects within those data structures.
First and foremost, I'd recommend using a java class to represent a single person entity... think about it, when you look up a person's information, you don't consult three separate books, or computer screens, or what have you, when all that information can be organized into one place. For your person above, for example, you could use something like this:
public class Person implements Comparable<Person> {
public String firstName;
public String lastName;
public int result;
public Person(String fn, String ln, int r) {
firstName = fn;
lastName = ln;
result = r;
}
public int compareTo(Person otherPerson) {
return lastName.compareTo(otherPerson.lastName);
}
}
This will give you an object that will store all of your person information, and by default will be easily sortable by last name (you can change this behavior with a comparator, which I won't cover here.)
Now instead of having three different arrays of first names, last names, and results, you can have a single array of Persons. There ARE actually sorting mechanisms within the java language for arrays already, which you can research and use if you choose, but if you'd like to use your own sort, you would just need to replace your swap conditional with something like this:
if(persons[index].compareTo(persons[index+1]) > 0) {
...
}
i just want ask you
why instead creating class student ie
class Student{
private String studentForename;
private String studentSurname;
private int studentResult;
//setters and getters
}
and put them in some collection ie List
you are putting them into 3 different arrays?
do you realize, if you have them nicely in the list, you can sort them just by using Collections.sort() ?
Can't understand properly the question: are you looking for a way to manually implement a sorting algorithm (bubble, quick or whatever) or you would like to simply sort them the best you can? Generally speaking you should never implement your own sort 'cause Java provides itself a very efficient lot... or is this an exercise? Probably :)
Best way I can imagine is, provided the 3 arrays in their original form are linked by index, create a surname/index map, load it form surname array, sort the Map.Entry by key and then you will have the array indexes sorted the way you wanted. Check here for more details: how to sort Map values by key in Java
PS The solutions provided by the others are correct and preferrable if you are NOT doing an exercise :) Better deal with a structured object than with 3 separated data.

Categories