How to access values stored in ArrayList in Java? - java

I'm a total newbie to Java, and until now all I've done was draw some shapes and flags. I'm struggling to understand the code I've been given. I need to access values stored in an ArrayList within another class. I'm not sure I'm making any sense, so here are the two classes Seat and Mandate:
package wtf2;
import java.util.*;
public class Seat {
public int index;
public String place;
public int electorate;
public String mp;
public String party;
public String prev;
public ArrayList<Mandate> results;
public Seat(int index, String place) {
this.place = place.trim();
this.index = index;
this.results = new ArrayList<Mandate>();
}
public void addMandate(Mandate m) {
//First candidate is always the MP
if (mp == null) {
mp = m.candidate;
party = m.party;
}
results.add(m);
}
public String toString() {
return "[" + this.index + "," + this.place + "]";
}
}
class Mandate {
public String candidate;
public String party;
public int vote;
public Mandate(String candidate, String party, int vote) {
this.candidate = candidate;
this.party = party;
this.vote = vote;
}
}
The main class contains code that feeds data from 2 text files into Seat and Mandate. From there I managed to access the date in Seat. Like here:
//Who is the MP for "Edinburgh South"
public static String qA(List<Seat> uk) {
for (Seat s : uk)
if (s.place.startsWith("Edinburgh South"))
return (s.mp);
return "Not found";
}
Now,instead of getting just the mp for Edinburgh South I need to get the vote values, compare them to each other, take the second biggest and display the associate party value.
Would appreciate any help, like how to access data from that Array would help me get started at least.

An element in an ArrayList is accesses by its index.
Seems you can just sort your ArrayList based on the vote values of the objects which are in the list.
For this you may want to look here: Sort ArrayList of custom Objects by property
Of course sorting is maybe too much for your given problem. Alternatively,
you may just iterate through the list and pick the two objects with the highest
votes values as you go.

Related

Allow Java method arguments to accept constructor paramaters

I'm trying to optimize a section of my code which requires an object array with constructor parameters in it. Is there a way to add that to the arguments of a method?
I have an array of objects called SongList in that array there are objects from the Song Class with constructor parameters:
songs[] songList = new songs[1];
songList[0] = new songs("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33);
I also have a method that searches the array based on the category and the search query:
//Method
public static songs[] search(songs SearchCategory , String Quarry){}
//Calling of method
search = AudioPlayer.search("aName", "Kenny Loggins");
Songs class:
public class songs {
String sName;
String fPath;
String aName;
double sLength;
public songs(String songName,
String filePath,
String Artist,
double songLength) {
sName = songName;
fPath = filePath;
aName = Artist;
sLength = songLength;
}
}
Is there a way I could make the first argument of the code accept a constructor parameter like Name? This would allow me to cut down the overall length of my code as I wouldn't need to use a switch statement.
Search method:
public static songs[] search(String SearchCategory , String Quarry){
//Returned array value
songs[] ReturnedResult = new songs[0];
// Method only list
List<songs> SearchResult = new ArrayList<songs>();
switch (SearchCategory) {
case "aName":
//for loop looks through all objects with the SearchCategory and places any found values into the list
for (songs songs : AudioListing) {
if (songs.aName.equals(Quarry)) {
SearchResult.add(songs);
}
}
case "sName":
for (songs songs : AudioListing) {
if (songs.sName.equals(Quarry)) {
SearchResult.add(songs);
}
}
case "fPath":
for (songs songs : AudioListing) {
if (songs.fPath.equals(Quarry)) {
SearchResult.add(songs);
}
}
case "sLength":
//Since the given quarry is a string and the length is a double the quarry is converted
double QuarryDoubleTypeC = Double.parseDouble(Quarry);
for (songs songs : AudioListing) {
if (songs.sLength == QuarryDoubleTypeC) {
SearchResult.add(songs);
}
}
}
// Conversion of list to array for ease of use
ReturnedResult = SearchResult.toArray(ReturnedResult);
return ReturnedResult;
}
There is a concept of reflection in Java that you can use here.
You can use the SearchCategory to get the field value from the object
Then you can use it to compare with Quarry
The working code is as below
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Songs {
String sName;
String fPath;
String aName;
double sLength;
static Songs[] AudioListing = new Songs[1];
static {
AudioListing[0] = new Songs("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33);
}
public Songs(String songName, String filePath, String Artist, double songLength) {
sName = songName;
fPath = filePath;
aName = Artist;
sLength = songLength;
}
public static Songs[] search(String SearchCategory, String Quarry) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
// Returned array value
Songs[] ReturnedResult = new Songs[0];
// Method only list
List<Songs> SearchResult = new ArrayList<Songs>();
for (Songs song : AudioListing) {
Field field = Songs.class.getDeclaredField(SearchCategory);
String fieldValue = (String) field.get(song);
if (fieldValue.equals(Quarry)) {
SearchResult.add(song);
}
}
// Conversion of list to array for ease of use
ReturnedResult = SearchResult.toArray(ReturnedResult);
return ReturnedResult;
}
#Override
public String toString() {
return "Songs [sName=" + sName + ", fPath=" + fPath + ", aName=" + aName + ", sLength=" + sLength + "]";
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
//Calling of method
Songs[] results = Songs.search("aName", "Kenny Loggins");
System.out.println(Arrays.toString(results));
}
}
This explains how it can be achieved you can further enhance your code after further exploring in this direction.
This is an excellent opportunity to leverage higher-order functions.
In Java, these are realized via Functional Interfaces.
You can reference the methods -- or fields -- from your Song class (which should be capitalized and singular, not songs) itself via Songs::aName. Furthermore, if you are trying to find a value, leveraging Predicate<Song> is an excellent idea.
Also, using Collections instead of arrays is advisable.
In short, your code could easily look like this:
class AudioPlayer {
List<Song> audioListings = new ArrayList<>();
public void add(Song song) { audioListings.add(song); }
public List<Song> search(Predicate<Song> predicate) {
return audioListings.stream()
.find(predicate)
.collect(Collectors.toList());
}
}
You would then use it like this:
AudioPlayer player = new AudioPlayer();
// fill with songs
player.add(new Song("Danger Zone", "danger zone.mp3", "Kenny Loggins", 3.33));
// find song with a specific aName
var songs = player.search(song => song.aName.equals("Kenny Loggins"));
The added benefit is that you can search for very complex things by constructing more complex predicates:
// find song with specific aName AND shorter then a given length
Predicate<Song> query =
song => song.aName.equals("Kenny Loggins")
.and(song => song.sLength <= 3.5);
var songs = player.search(query);
I would advise against using reflection for this. Reflection comes with a whole range of problems and it simply isn't needed. The approach I have outlined above is far more idiomatic Java since Java 8, scales better, is easier to read, less error-prone and overall cleaner.
What you're looking for is a bit advanced; it's the interface Function<Song, String>. This will allow you to provide some transformation that selects a string value for your Song object, particularly in this case such options as Song::getSName. This is how it would be done with streams (and collections):
songList.stream()
.filter(song -> quarry.equals(function.apply(song)))
.findAll();
However, I strongly recommend that you become more familiar with the basics of Java before diving into more complicated logic, especially standards about naming (classes should be capitalized; variables should not), collections (lists are usually preferred over arrays), static vs. instance members, and interfaces.

how can I improve my code for this task

I am newbie to object orientated programming and trying to construct something which resembles a basic vote counter which should take an int parameter that represents a choice of two candidates and print the election results to the terminal window. albeit (the votes attributable to each candidate and the total votes cast)
The method I am looking for should also return a string that gives information on the success or failure of casting the vote.”your vote has been cast” “invalid choice, no vote cast"
I have created a class and the constructors and also implemented some basic get methods.
I am wondering how I should go about achieving this objective albeit through a conditional statement or using some sort of advanced method.
any help in terms of the syntax or wider approach would be appreciated.
public class VoteCounter {
private String candidate1;
private String candidate2;
private int candidate1Votes;
private int candidate2Votes;
private boolean completed;
public VoteCounter(String candidate1, String candidate2) {
this.candidate1 = candidate1;
this.candidate2 = candidate2;
this.candidate1Votes = 0;
this.candidate2Votes = 0;
this.completed = false;
}
public VoteCounter() {
this("CANDIDATE 1", "CANDIDATE 2");
}
public String getCandidate1 () {
return this.candidate1;
}
public String getCandidate2 () {
return this.candidate2;
}
public Boolean getCompleted () {
return this.completed;
}
public void setCompleted (boolean completed) {
this.completed = completed;
}
}
Something like this?
private String vote(int choice)
{
if(choice == 1)
{
candidate1Votes++;
}
else if(choice == 2)
{
candidate2Votes++;
}
else
{
return "invalid choice, no vote cast";
}
return "your vote has been cast";
}
I would do that in more general manner, avoiding code duplication and allowing to change number of candidates easily.
So let's make a class Vote similar to your VoteCounter but only for one candidate, with following fields:
private String candidate; // init this in constructor
private int candidateVotes; // initially 0, so no need to init
and with vote() method like in other answer but also without a candiadate, so:
public void vote() {
candidateVotes++;
}
Then you can make class VoteCounter which will take any number of candidates and will keep them in Array or Map.
Map<Integer, Vote> votes = new HashMap<>();
then you're creating vote method with choice:
public void vote(int choice) {
votes.get(choice).vote();
}
Then all is left is to iterate through your votes map and find the one with biggest number of votes.

How to add a Course object to an array via an addCourse() method

I am having issues with objects and classes.
I had to define two classes:
Course: a course has a code, an name and a number of credits
Teacher: a teacher has a first name and last name. He can be asked his full name.
So far so good, I got no issue with them, but I have to do next assignment which I was trying to do in the last 2 days and I could not find a proper answer:
Extend the code of the class teacher. A teacher also has a list of courses he can teach. Add an array of Courses to the code. Also add a function addCourse(Course aCourse) to the code. Courses can also be removed from teachers.
I could do everyting in my way but no clue on how to create the addCourse(Course aCourse) method.
Find below my coding, but it must be according to the method described:
public class Course {
private String courseCode;
private String courseName;
private String numberOfCredits;
public Course(String courseCode, String courseName, String numberOfCredits) {
super();
this.courseCode = courseCode;
this.courseName = courseName;
this.numberOfCredits = numberOfCredits;
}
public void print() {
System.out.println(courseCode + "\t" + courseName + "\t" + numberOfCredits);
}
public static void main(String[] args) {
Course[] courseArray = new Course[4];
System.out.println("Code" + "\t" + "Name" + "\t" + "Credits");
courseArray[0] = new Course("001", "Hist", "3");
courseArray[1] = new Course("002", "Phy", "3");
courseArray[2] = new Course("003", "Math", "3");
courseArray[3] = new Course("004", "Log", "3");
for (int i = 0; i < courseArray.length; i++) {
courseArray[i].print();
}
}
}
Arrays are fixed length collections of objects, so you'll need to decide how big your array should be. Let's call the length of your array MAX_COURSES. A more advanced solution might resize the array when required, but I get the impression this is beyond the scope of your course.
So you need to define the Course[] array as a field of your Teacher class. The syntax of array declarations is quite easy to research, so I won't put that in here. Just make sure your array length is equal to MAX_COURSES.
Now, to add courses to the array, you need to know where to put them. To keep track of the next free position of the array, the easiest thing to do is to declare a field in your class:
private int numCourses = 0;
Now, when you add a new course, insert the course into the index specified by numCourses. Make sure you increment numCourses after you've added the course.
Finally, you ought to test to see if your array is full before you agree to insert a new course into the array, i.e. check if numCourses is smaller than MAX_COURSES. If it's not, you need to throw an exception.
I would recommend using a collection (such as a List) rather than an array. The code would look something like:
public class Teacher {
private final String firstName;
private final String lastName;
private final List<Course> courses = new ArrayList<Course>();
public Teacher(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void addCourse(Course course) {
courses.add(course);
}
}
Based on that example, you should be able to add the removeCourse method yourself, and any other method you need to operate on the list of courses.
If you want to return the list as an array, you could always convert it, e.g:
public Course[] getCourses() {
return courses.toArray(new Course[courses.size()]);
}
If you really need to use an array for the data structure based on your assignment, something you can try when adding and removing courses, is to construct a list from the array of courses, add or remove a course from that list, the convert the list back to an array of courses.
There's really 3 options here.
Option 1
If you're allowed to use List constructs:
private List<Course> courses = new ArrayList<Course>();
public void addCourse(Course aCourse)
{
if (aCourse == null)
{
return;
}
courses.add(aCourse);
}
Option 2
The uses arrays, but it doesn't scale. Assume that a teacher can only have a maximum of X courses, in my example 10:
// Yes, I stole Duncan's variable names
private final int MAX_COURSES = 10;
private int numCourses = 0;
private Course[] courses = new Course[MAX_COURSES];
public void addCourse(Course aCourse) {
if (aCourse == null)
{
return;
}
if (numCourses >= courses.length)
{
return;
}
courses[numCourses] = aCourse;
numCourses++;
}
Option 3
This is identical to the previous item, but is a bit smarter in that it can resize the array... by creating a new one using the static method Arrays.copyOf
// Yes, I stole Duncan's variable names
private final int MAX_COURSES = 10;
private int numCourses = 0;
private Course[] courses = new Course[MAX_COURSES];
public void addCourse(Course aCourse) {
if (aCourse == null)
{
return;
}
if (numCourses >= courses.length)
{
int size = courses.length * 2;
courses = Arrays.copyOf(courses, size);
}
courses[numCourses] = aCourse;
numCourses++;
}

Checking if there is a certain string in an object contained in an ArrayList, then adding the object to another ArrayList

I have Arraylist of objects ArrayList<Product> productDatabase. The object contains a String and a double and then these objects will be added to the productDatabase by addProductToDatabase(); as follows:
public void addProductToDatabase(String productName, double dimensions); {
Product newProduct = new Product(ProductName, dimensions);
productDatabase.add(newProduct);
}
I also want to make an Arraylist<ProductCount> productInventory which counts how many Product are accounted for. Before it can add to ArrayList<ProductCount> productInventory however, it should first check if the object details exist in the productDatabase while running addProductToInventory()
public Product getProduct(String name) {
for(i = 0; i < productDatabase.size(); i++)
if(productDatabase.get(i).contains(name) //Error: cannot find symbol- method contains.(java.lang.String)
return productDatabase.get(i)
}
public void addProductToInventory(String productName, double quantity)
{
Product p = getProduct(name);
productCount.add(new ProductCount(o, quantity));
}
Assume that you always have different objects (so nothing will have the same name), but you're always unsure of the dimensions (so when you input the same producttName + dimensions you edit the dimensions in it).
At the end of the day, you have to put all the items in it a large box and report what you've inventoried, so you also have a getProductQuantityTotal() and you have to getProductDimensionTotal()-- as the name suggests, get the total of number of objects you've counted, and the sum of the dimensions.
What do I have to add/change/remove about this code? Don't consider syntax first (because BlueJ checks for common syntax errors and I just typed this by hand). I'm sure that I'm missing a for statement somewhere, and I'm probably misusing contains() because it won't recognise it (I have import java.util.*; and import java.util.ArrayList;)
To answer the question in your post title: How to find a string in an object, for a list of those objects, here is some sample code that does this:
First, I created a trivial object that has a string field:
class ObjectWithStringField {
private final String s;
public ObjectWithStringField(String s) {
this.s = s;
}
public String getString() {
return s;
}
}
And then a code that populates a list of it, and then searches each for the string. There's no magic here, it just iterates through the list until a match is found.
import java.util.List;
import java.util.Arrays;
/**
<P>{#code java StringInObjectInList}</P>
**/
public class StringInObjectInList {
public static final void main(String[] ignored) {
ObjectWithStringField[] owStrArr = new ObjectWithStringField[] {
new ObjectWithStringField("abc"),
new ObjectWithStringField("def"),
new ObjectWithStringField("ghi")};
//Yes this is a List instead of an ArrayList, but you can easily
//change this to work with an ArrayList. I'll leave that to you :)
List<ObjectWithStringField> objWStrList = Arrays.asList(owStrArr);
System.out.println("abc? " + doesStringInObjExistInList("abc", objWStrList));
System.out.println("abcd? " + doesStringInObjExistInList("abcd", objWStrList));
}
private static final boolean doesStringInObjExistInList(String str_toFind, List<ObjectWithStringField> owStrList_toSearch) {
for(ObjectWithStringField owStr : owStrList_toSearch) {
if(owStr.getString().equals(str_toFind)) {
return true;
}
}
return false;
}
}
Output:
[C:\java_code\]java StringInObjectInList
abc? true
abcd? false
In the real world, instead of a List, I'd use a Map<String,ObjectWithStringField>, where the key is that field. Then it'd be as simple as themap.containsKey("abc");. But here it is implemented as you require. You'll still have quite a bit of work to do, to get this working as specifically required by your assignment, but it should get you off to a good start. Good luck!

How can I print out an arraylist and also How can I add errors checks to the arraylist?

I have been trying to solve this problem for ages and with no luck I didn't progress. Could someone please help me out. I have created an arrayList, made an getter class, have made a method. I can add stuff to the array list as well but when I print the arrayList out it prints out some random text.
below is the arrayList I created.
public static ArrayList<getArrayList> arrayList = new ArrayList<getArrayList>();
here is my method;
private static void addToArrayList(String a, double no1, int no2, int no3) {
try {
arrayList.add(new getArrayList(a, no1, no2, no3));
} catch (Exception e) {
e.printStackTrace();
}
}
here is my getter class
public class getArrayList {
private String name;
private double seconds;
private int speed1;
private int speed2;
public String getName() {
return name;
}
public double getSeconds() {
return seconds;
}
public int getSpeed1() {
return speed1;
}
public int getSpeed2() {
return Speed2;
}
public StoreCommands(String storeName, double storeSeconds, int storeSpeed1, int storeSpeed2) throws Exception{
name = storeName;
seconds = storeSeconds;
speed1 = storeSpeed1;
speed2 = storeSpeed2;
}
}
to add stuff on this list I use the method I created
addToArrayList(String a, double no1, int no2, int no3) filled in with my values
and to receive stuff from the arraylist I use this
for(getArrayList s : arrayList) {
System.out.println(arrayList + "\n")
;
and it prints out if i use System.out.println(arrayList), depending on how much I add to the arraylist.
[StoreCommands#49a21b63]
Besides that could someone tell me how I can set a size of the arrayList so if anything more that is being added it won't add and give an error.
Also I need to perform certain error checks once the items are in the arrayList
*1st If the an item is added to the list and the user tries to add the same one again straight after I want to display an error.. (the user can add the same stuff but not directly after the one they just added, they will need to add something else first)
*2nd if say user wants to add apples to the list, I want to limit that to only 2 time in the whole list, more than that will not be added and will display and error.
Could someone help me out please, I will really appreciate it.
Thanks.
Try this -
for(getArrayList s : arrayList)
System.out.println(s + "\n");//This print the tostring of getArrayList class
Again override the toString method of getArrayList class, to print actual field value of the object. Example -
public class getArrayList {
public String toString(){
return name +"||" +seconds+"||"+ speed1+"||"+speed2;
}
}
Note : Follow java nomenclature standard, first later of you class name would be capital And also give a relevent name to the Class.
Overriding toString method will help you to print actual data. Override it in your class getArrayList. One more thing is class name should start with capital letter.
public String toString()
{
return "Name : "+name+" Seconds : "+seconds+" Speed1 : "+speed1+" Speed2 : "+speed2;
}
and use it like
for(getArrayList s : arrayList)
System.out.println(s.toString);
You can limit the size by adding check to
private static void addToArrayList(String a, double no1, int no2, int no3) {
try
{
if(arrayList.size < 10) //any size you want
arrayList.add(new getArrayList(a, no1, no2, no3));
else
System.out.println("ArrayList is full");
} catch (Exception e) {
e.printStackTrace();
}
}
You don't have to loop in order to print an array, just do:
System.out.println(Arrays.toString(arrayList.toArray()));
ArrayList doesn't have a mechanism to limit the size, if you want to do it - you'll have to implement it.
Example:
import java.util.ArrayList;
/**
* User: alfasin
* Date: 2/5/14
*/
public class RestrictedSizeArrayList<E> extends ArrayList<E> {
private static final int limit = 6;//example
#Override
public boolean add(E e){
if(this.size() > 5){
throw new IndexOutOfBoundsException("Can't add more than 5 elements to the ArrayList");
}
boolean result = super.add(e);
return result;
}
}

Categories

Resources