I made a contact list with three classes, the ContactList class holds an array which stores Last Name, First Name, Street, City, State, ZIP, Country, Email, Phone No., and Notes.
I want to implement a search function by last name into the class of ContactList, where it shows all the information of the contact who has the last name the user searched for, but i cant seem to get anything to work. :(
import java.util.*;
public class ContactList {
//declaration of an array and its attributes
private final int SIZE = 10;
private Person [ ] list;
private int nextEmptyElementInArray = 0;
// Constructor for ContactList object
public ContactList () {
list = new Person [SIZE];
}
// Method that adds a new contact into the array
public void addNewContact() {
list[nextEmptyElementInArray] = new Person();
list[nextEmptyElementInArray].read();
nextEmptyElementInArray++;
}
// Method retrieves contacts by last name
int searchByLastName(Person [] list) {
Scanner console;
console = new Scanner(System.in);
String searchByLastName = console.next();
for (int i= 0; i< list.length; i++) {
if (list[nextEmptyElementInArray].lastName.equals(searchByLastName))
return i;
}
return -1;
}
}
Your list subscript appears to be wrong: for each iteration of the loop you're doing this:
if (list[nextEmptyElementInArray].lastName.equals(searchByLastName))
If I understand the question correctly, you should be doing this:
if (list[i].lastName.equals(searchByLastName))
Also, be careful about naming your variable the same as the function. At best it'll cause confusion.
[Edit] Just noticed you're pre-allocating the list, then managing actual content length using nextEmptyElementInArray. Your for loop should probably go something like this:
for (int i= 0; i< nextEmptyElementInArray; i++)
I suggest to change the search method as
int searchByLastName(Person [] list, String lastName) {
for (int i= 0; i < list.length; i++) {
if (list[i].lastName.equals(lastName))
return i;
}
}
return -1;
}
read lastName from console outside this function and pass it as a search param
Related
I have an object array containing two fields per object.
I have to write a method that will sort my array by the first field.
I already have a method which extracts the first field from each object
I always get an error message when I call my method to sort.
Here is my code:
public static void trier(String[]code, String[]nom, int nbObj) {
for(int i = 0; i < nbObj-1; i++) {
int indMin = i;
for (int j = i+1; j < nbObj; j++)
if (code[j].compareTo(code[indMin]) < 0)
indMin = j;
if (indMin != i) {
// permutation :
String tempo = code[i];
code[i] = code[indMin];
code[indMin] = tempo;
// permutation :
String temp = nom[i];
nom[i] = nom[indMin];
nom[indMin] = temp;
}
}
}
and the call :
Classe.trier(tableau, tableau, nbObj);
I also tried Class.sort(array.getCode(), array.getName(), nbStudent);
But I still have compilation errors
thank you in advance for your help
First of all, you don't have to use 2 separate arrays to contain your data. You can put everything in a single array, but better way is to use Java Collections. Perfect choice is ArrayList. However, you still better combine two fields into a single object. You can do it like this:
public class MyObject {
String code;
String nom;
MyObject(String code, String nom) {
this.code = code;
this.nom = nom;
}
}
Now you have a class containing 2 fields. Your aim is to sort a collection of such objects by their second field (nom). You can do this easily since Java 8:
public static void sort1(ArrayList<MyObject> list) {
list.sort((obj1, obj2) -> obj1.nom.compareTo(obj2.nom));
}
Or
public static void sort2(ArrayList<MyObject> list) {
list.sort(Comparator.comparing(MyObject::getNom));
} // However for this you need to add method getNom to MyObject
Remember to put your objects in the collection properly.
For example:
MyObject a = new MyObject("abc", "abide");
MyObject b = new MyObject("cab", "whatever you want");
ArrayList<MyObject> list = new ArrayList<>();
list.add(a);
list.add(b);
trier(list);
I'm trying to create a FileIO where random numbers are placed into a .txt file and outputted, sorted in another .txt file. I have a bubble sort code that can sort numbers & I have another code that makes a .txt file. I'm just not sure how I'd implement these 2 together.
Here's my fileIO code:
public static void main(String[] args) {
File file = new File("test.txt");
//Writes name and age to the file
try {
PrintWriter output = new PrintWriter(file);
output.println("Rober");
output.println(27);
output.close();
} catch (IOException ex) {
System.out.printf("ERROR: %s\n", ex);
}
//Reads from the file
try {
Scanner input = new Scanner(file);
String name = input.nextLine();
int age = input.nextInt();
System.out.printf("Name: %s Age %d\n", name, age);
} catch (FileNotFoundException ex) {
System.out.printf("ERROR: %s\n", ex);
}
}
And here is my bubble sort code:
public static void main(String[] args) {
Random num = new Random();
//Creating an array for 10 integers
int [] number = new int [10];
System.out.print("Random Numbers:");
/*Display the unsorted numbers in a random order.
These numbers range from 0 to 100
*/
for (int d = 0 ; d<number.length ; d++){
/* We add a "+1" to the nextInt(100) here because then the numbers
will only range from 0 to 99.
*/
int RandomG = num.nextInt(100)+1;
number[d] = RandomG;
System.out.print(" " +RandomG);
}
//Display the sorted numbers
System.out.print("\nSorted Numbers:"+Arrays.toString(BubbleSortAsceMethod(number)));
}
public static int [] BubbleSortAsceMethod(int[] number){
int placeholder;
for(int i = 0 ; i < number.length-1 ; i++){
for ( int x = 1 ; x < number.length-i ; x++){
/*If the first number in the sequence is greater than the second
number, than save the first number of sequence in placeholder
and place the second number in the first numbers position, and
put the placeholder in the second numbers position (SWAP).
*/
/*
Since this is saying that when the first term is bigger than the
2nd term, the sequence will increase. If we flip the relational
operator, the sequence will decrease.
*/
if ( number[x-1] < number[x]){
placeholder = number[x-1];
number[x-1] = number[x];
number[x] = placeholder;
}
}
}
return number;
}
I'm kinda new to all this java stuff so please go a bit easy on me! Any help at all is appreciated :)
As the data contained in the file will consist of a pair of values: The name (String) and the age (int), you will need to retain their relationship. The best way of doing this would be to create a Class to represent the data. Eventually you want to sort the data on age using your BubbleSort method. While practically this would not be your first choice to sort data, I assume that this is a requirement. The BubbleSort method you have sorts an int[] by comparing each entry against it's immediate neighbor. With int being primitive, you can directly compare each element using the < operator.
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
#Override
public String toString() {
return name + System.lineSeperator() + age;
}
#Override
public int compareTo(Person person) {
return this.age - person.age;
}
}
You may want to implement the Comparable interface to compare Objects; in which the interface must be implemented by Overriding the compareTo(Person person) method. You can impose sorting on age by returning the difference in age. This is not the only way you can impose the order you want; you may wish to compare directly using the getAge() of each Object or create a Comparator object.
Using the Comparable interface does allow you to make your BubbleSort class more generic, however (though the array must be of Objects that implement the interface; hence no primitive types).
public class BubbleSort {
public static <T extends Comparable> T[] BubbleSortAsceMethod(T[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int x = 1; x < array.length - i; x++) {
if (comparator.compare(array[x - 1], array[x]) < 0) {
T placeholder = array[x - 1];
array[x - 1] = array[x];
array[x] = placeholder;
}
}
}
return array;
}
}
You will notice that this sort method has some slight differences from your original, namely the BubbleSortAsceMethod method signature with the introduction of generic type parameters. Once again, this is completely optional, though this does give you the flexibility to use this method in the future for other arrays of Classes that extend the Comparable interface.
If you don't want to use generics or the Comparable interface, you will need to change the method signature and if statement.
You're method signature should instead look like public static Person[] BubbleSortAsceMethod(Person[] array) and the if statement if (array[x-1].getAge() < array[x].getAge())
This can give you an illustration of it working, though this does not consider the file io which should be simple to implement from what you have done already.
static Random random = new Random();
public static void main (String args[]) {
int size = 100;
Person[] peopleArray = new Person[size];
for (int i = 0; i < size; i++) {
String name = generateName(random.nextInt(4) + 4);
int age = random.nextInt(100);
peopleArray[i] = new Person(name, age);
}
peopleArray = BubbleSort.BubbleSortAsceMethod(peopleArray);
}
Note that this conforms, at least as much as possible, to the code you have implemented this far. If the BubbleSort and use of arrays are not critical, data structures that implement the List interface, such as ArrayList, can allow you to implement this much cleaner. This does not use the BubbleSort method at all.
public static void main (String args[]) {
int size = 100;
ArrayList<Person> people = new ArrayList<>();
for (int i = 0; i < size; i++) {
String name = generateName(random.nextInt(4) + 4);
int age = random.nextInt(100);
people.add(new Person(name, age));
}
peopleList.sort(Person::compareTo);
//or, if you don't want to implement comparable
peopleList.sort(Comparator.comparing(Person::getAge));
}
Appendix:
Used for illustrative purposes: Generates a name of a set length (randomly).
static char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
public static String generateName(int length) {
if (length > 0) {
return alphabet[random.nextInt(alphabet.length)] + generateName(length - 1);
}
return "";
}
sorry if this has been posted under a different title which I'm sure it has but I failed at finding it.
Say you have the following code:
public class Main{
public static void main(String[] args)
{
String[] names = {"James", "Allison"};
int[] ages = {10, 12};
for (int i = 0; i < names.length; i++)
{
Item names[i] = new Item(ages[i]);//line that will produce the error
}
}
class Item{
private int age;
Item(int theirAge){
age = theirAge;
}
}
Now this code will produce a duplicate variable error which comes from the names[i] variable already being defined as a String but now we are trying to define it as an Item. I have tried quite a few things but just can't seem to get it.
public class Main {
public static void main(String[] args){
String[] names = {"James", "Allison"};// variable a
int[] ages = {10, 12};
for (int i = 0; i < names.length; i++){
Item names[i] = new Item(ages[i]);//variable b
}
}
class Item{
private int age;
Item(int theirAge){
age = theirAge;
}
}
Because you have two variables have the same name, variable a and variable b. The solution for you would be either you change the variable b's name, or use the existing variable without declaration it again. However, in this case, you have different type from A to B. You cannot use the existing variable. You just have to declare a new Item object, but different name.
Hope it helps.
I have one class which is called people where I keep track of 50 people, their rank, name, age and order. Then I have a second class called rearrange where I have to change the position of the int order. So it will change up the order, like order 1 which is in position 0, will be moved to position 48th. I need to do the whole thing without using any loop.
class people {
int order[] = new int[50];
for(int j=0; j<order.length; j++) {
order[j] = "order" + j;
System.out.print(order);
}
}
class rearrange {
// In here i need to change the position of the int order, and need to do this without using any loop.
}
Shouldn't rearrange be a method of the people class? Classes are usually created for Nouns, Verbs are usually functions or methods of a class. And wouldn't it be better to have a class "Person" and make an array of 50 of them, and simply change their index to change their order?
Consider something like this:
public class Person //create Person class with the attributes you listed
{
private int rank;
private int age;
private String name;
public Person(int rank, int age, String name) //constructor
{
this.rank = rank;
this.age = age;
this.name = name;
}
}
public class MainClass
{
Person[] people = new Person[50]; //array of Persons, containing 50 elements
public static void main(String[] args)
{
for(int i = 0; i < people.length(); i++)
{
people[i] = new Person(something, something, something); //give all the people some values, you'll have to decide what values you are giving them
}
//do something with the rearrange function here
}
public static void rearrange(int target, int destination) //this is just a "swap" function
{
Person temp = people[destination];
people[destination] = people[target];
people[target] = temp;
}
}
So what I'm trying to do here is initialize my strings to an empty string and my ints to 0. The display report is kind of a debugger at the moment, and when I run the program that calls displayReport, it only displays my ints and strings as null. It has to be something in my for loop, but I can't seem to figure out what I am doing wrong.
EDIT: To be clear, I HAVE to use private void initializeString(String[] s) and private void initializeInt(int[] a). And my constructor has these guidelines
public constructor: Initializes arrays holding soft drink name and ID to hold all empty strings (calls intitializeString twice to perform the tasks). Initializes arrays holding starting inventory, final inventory, and the counts of the number of transaction to zero (calls initializeInt three times to perform the tasks).
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class SoftDrinkInventory {
static final int MAXSIZE = 100; // maximum size of 100
private String[] names; // softdrink names
private String[] ids; // softdrink identifications
private int[] startingInventory; // starting inventory of the softdrinks
private int[] finalInventory; // final inventory of the softdrinks
private int[] transactionCounts; // number of transactions per softdrink
private int trueSize; // total number of softdrinks
/**-----------------------------------------------------------------------
* constructor
*
* Initializes arrays holding soft drink name, ID number to the
* empty string. Initializes starting inventory, final inventory,
* and transaction counts are to zero.
*/
public SoftDrinkInventory() {
initializeString(names);
initializeString(ids);
initializeInt(startingInventory);
initializeInt(finalInventory);
initializeInt(transactionCounts);
}
/**-----------------------------------------------------------------------
* displayReport
*
* Displays a report including soft drink name, ID, starting inventory,
* final inventory, and number of transactions processed.
*/
public void displayReport() {
System.out.printf("%-22s %-16s %-23s %-23s %s %n", "Soft Drink", "ID",
"Starting Inventory", "Final Inventory",
"# transaction");
for(int i = 0; i < 10; i++) {
System.out.printf("%-22s %-16s %-23f %-23f %f %n", names, ids,
startingInventory, finalInventory,
transactionCounts);
}
}
/**-----------------------------------------------------------------------
* initializeInt
*
* Takes an int array parameter and initializes its array values to zero.
* #param a int array
*/
private void initializeInt(int[] a) {
a = new int[MAXSIZE];
for(int i = 0; i < a.length; i++) {
a[i] = 0;
}
}
/**-----------------------------------------------------------------------
* initializeString
*
* Takes a String array parameter and initializes its array values to
* the empty string.
* #param s string array
*/
private void initializeString(String[] s) {
s = new String[MAXSIZE];
for(int i = 0; i < s.length; i++) {
s[i] = "";
}
}
}
Java uses pass by value. This means the references you pass in are being modified, not the originals. The simplest solution is to return the array you want.
names = initialiseString(100);
However, a better approach is to use a List of Objects like
private final List<Item> items = new ArrayList<>();
// to add
items.add(new Item("name", "id", 1234, 10, 1224));
// you can add any size 0 up to 2 billion.
int actualSize = items.size();
class Item {
private String name; // softdrink name
private String id; // softdrink identification
private int startingInventory; // starting inventory of the softdrink
private int finalInventory; // final inventory of the softdrink
private int transactionCount;
}
You can't overwrite a reference, that was passed as an argument to a method, inside that method. When you're doing a = new int[MAXSIZE]; you are creating an array that is visible only to that method. What you need to do is return the created array. You might consider doing something like this:
private int[] initializeInt(int size) {
...
}
...
startingInventory = initializeInt(MAXSIZE);
Because you are initializing the arrays local to those initializing methods. Instead of passing argument to the methods, simply create and initialize a new array within the methods and return those arrays to respective instance variables.
For example change your initializeString(String[]) to public String[] initializeString() and within this method write.:
String[] names = new String[MAXSIZE];
for(int i = 0; i < names.length; i++) { names[i] = "";} return names;
And then call this method within your constructor as follows
names = initializeString();
There are Java functions that take an array as a parameter, put data in the array, and it is available to you.
For example:
BufferedReader.read(char[] cbuf, int off, int len)
However, you must first create the array, and it just fills it. So you must first do this before calling that function:
char[] cbuf = new char[100];
Since your methods are initializing arrays in the same class, you can just do Vishal K said, and not pass the arrays to the methods. In situations where you are calling methods elsewhere, you can pass objects as parameters to methods in other classes as long as you create the object first. The callee can use the passed reference to modify your object.
Of course there are better ways to do this (such as using List of Objects, as suggested by Peter Lawrey), but since this is in the specs you have, you can try this: when you declare your arrays, also allocate memory for them :
private String[] names = new String[MAXSIZE]; // softdrink names
private String[] ids = new String[MAXSIZE]; // softdrink identifications
private int[] startingInventory = new int[MAXSIZE]; // starting inventory of the softdrinks
private int[] finalInventory = new int[MAXSIZE]; // final inventory of the softdrinks
private int[] transactionCounts = new int[MAXSIZE]; // number of transactions per softdrink
Then, in your functions, you can simply assign values to 0 and empty String:
private void initializeInt(int[] a) {
for(int i = 0; i < a.length; i++) {
a[i] = 0;
}
}
and
private void initializeString(String[] s) {
for(int i = 0; i < s.length; i++) {
s[i] = "";
}
}
Please note that you have an error in your displayReport() function too. You are using %f to display int values (%f is used for floats). Instead, change it to %d. Also, in your for loop, you are not actually looping through your arrays. Just use i as an index when iterating. Another thing is that you are displaying only 10 entries, whereas your MAXSIZE, which you use to initialise arrays is 100, so if you want to display all array elements, change 10 to MAXSIZE:
public void displayReport() {
System.out.printf("%-22s %-16s %-23s %-23s %s %n", "Soft Drink", "ID",
"Starting Inventory", "Final Inventory",
"# transaction");
for(int i = 0; i < MAXSIZE; i++) {
//change "%-22s %-16s %-23f %-23f %f %n" to the below
//and names etc. to names[i] etc.
System.out.printf("%-22s %-16s %-23d %-23d %d %n", names[i], ids[i],
startingInventory[i], finalInventory[i],
transactionCounts[i]);
}
}