Sorting an array of objects by two doubles - java

So I had a delimited file that I read into an array.
array[0] is the boxID (double)
and
array[1] is the movieID (double)
I have no clue how I'd be able to sort my array by these two doubles. Any comments? I've tried looking at other questions on this website but I just got confused by them. I'm currently in my first programming class.
Movies[] newMasterMovies = new Movies[200];
int newMasterCount = 0;
int masterCount = 0;
int updateCount = 0;
while (updateCount < updateTotalCounter || masterCount < masterTotalCounter) {
String updateCompare = updateMovies[updateCount].getBoxID() + updateMovies[updateCount].getMovieID();
String masterCompare = masterMovies[masterCount].getBoxID() + masterMovies[masterCount].getMovieID();
int compare = updateCompare.compareTo(masterCompare);
if (compare > 0) {
newMasterMovies[newMasterCount] = masterMovies[masterCount];
masterCount++;
newMasterCount++;
}
if (updateMovies[updateCount].getActionCode() == "A") {
newMasterMovies[newMasterCount] = updateMovies[updateCount];
updateCount++;
newMasterCount++;
}
if (updateMovies[updateCount].getActionCode() == "D") {
updateCount++;
masterCount++;
}
if (updateMovies[updateCount].getActionCode() == "C") {
newMasterMovies[newMasterCount] = updateMovies[updateCount];
updateCount++;
newMasterCount++;
masterCount++;
}
}
That is what my array looks like that I am trying to sort. I tried to do a selection sort but got confused since I want to sort by two properties, not just one.

This guy here does a wonders
Arrays.sort(iArr);
Here is what it can do:
Here is an example code
public class ArrayDemo {
public static void main(String[] args) {
// initializing unsorted int array
int iArr[] = {2, 1, 9, 6, 4};
// let us print all the elements available in list
for (int number : iArr) {
System.out.println("Number = " + number);
}
// sorting array
Arrays.sort(iArr);
// let us print all the elements available in list
System.out.println("The sorted int array is:");
for (int number : iArr) {
System.out.println("Number = " + number);
}
}
}
And the results should be like this
Number = 2
Number = 1
Number = 9
Number = 6
Number = 4
The sorted int array is:
Number = 1
Number = 2
Number = 4
Number = 6
Number = 9
Hopes this helps some

To simply sort your Movies[] you can use Arrays.sort and use a custom Comparator. Like this:
Arrays.sort(masterMovies, new Comparator<Movies>() {
#Override
public int compare(Movies o1, Movies o2) {
// compare boxID
// compare movieID
return 0; // return result
}
});
Arrays.sort use merge sort or binary insertion sort which are both more stable and faster than selection sort.
If you insist to do your selection sort, try to edit yor class Movies to implement Comparable interface, like this: class Movies implements Comparable<Movies>. And implement compareTo method like this:
#Override
public int compareTo(Movies o) {
// compare boxID
// compare movieID
return 0; // return result
}
And change your old compare code int compare = updateCompare.compareTo(masterCompare); to int compare=updateMovies[updateCount].compareTo(masterMovies[masterCount]);, then go on.

Related

How could I get this Insertion Sort code in alphabetical order?

I am new to coding and I put my code in order going from least amount of letters to greatest amount. Please help me understand how to put the code into alphabetical order.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] a = new String[] {"bread", "milk", "cheese", "spinach", "apple", "peanuts"};
System.out.println("Before Sort:" + Arrays.toString(a));
insertionSort(a);
System.out.println("After Sort: " + Arrays.toString(a));
System.out.println();
a = new String[] { "Allison", "Neha", "Charley", "Jason", "Tyson", "Miles", "Riley" };
System.out.println("Before Sort:" + Arrays.toString(a));
insertionSort(a);
System.out.println("After Sort: " + Arrays.toString(a));
}
public static void insertionSort(String[] a) {
// Move the marker from index 1 to the last index
for (int i = 1; i < a.length; i++) {
// Insert the element at the marker to the right position
insert(a, i);
}
}
public static void insert(String[] a, int marker) {
String unsortedElement = a[marker];
// shift other elements to the right to create the correct position
int correctPosition = marker;
for (int i = marker - 1; i >= 0; i--) {
if (a[i].length() > unsortedElement.length()) {
a[i + 1] = a[i];
correctPosition--;
}
else {
break; // stop looping
}
}
// Insert the unsorted element to the correct position
a[correctPosition] = unsortedElement;
}
}
You have to change the condition inside the insert() method.
Comparison of String objects could be done using method compareTo.
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#compareTo(java.lang.String)
Compares two strings lexicographically. The comparison is based on the
Unicode value of each character in the strings.
Returns: the value 0 if the argument string is equal to this string; a value less than 0 if this string is lexicographically less
than the string argument; and a value greater than 0 if this string is
lexicographically greater than the string argument.
In other words, you may visualize what the method compareTo() does is like a 'weighting' of those strings using scales.
If 'weights' are equal the compareTo() returns 0, if the first string is 'lighter' than the second (a string that is passed as an argument) a 'scales' (compareTo()) will give you a negative value.
That's why the condition in the code below is written as
unsortedElement.compareTo(a[i]) < 0
public static void insert(String[] a, int marker) {
String unsortedElement = a[marker];
// shift other elements to the right to create the correct position
int correctPosition = marker;
for (int i = marker - 1; i >= 0; i--) {
if (unsortedElement.compareTo(a[i]) < 0) {
a[i + 1] = a[i];
correctPosition--;
}
else {
break; // stop looping
}
}
// Insert the unsorted element to the correct position
a[correctPosition] = unsortedElement;
}
OUTPUT:
Before Sort:[Allison, Neha, Charley, Jason, Tyson, Miles, Riley]
After Sort: [Allison, Charley, Jason, Miles, Neha, Riley, Tyson]
you can sort the hole array at once using static method Arrays.sort(arr)
import java.util.Arrays;
...
String[] arrayOfStrs = {"d","a","ca"};
Arrays.sort(arrayOfStrs);
// arrayOfStrs is now ["a","ca","d"]
To sort it from less to more amount of letrers create first a Comparator class that uses the String length:
public class StringLengthComparator implements Comparator<String> {
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
}
And then use it in the Arrays.sort(...) method:
Arrays.sort(a, new StringLengthComparator());
To sort them alphabetically you just need this:
Arrays.sort(a);

How to compare two Array List of different types?

I have taken a Class type ArrayList (1 String, 6 int) and now I have to compare the numbers with another array. How can I compare them?
ArrayList<customer> customerArray= new ArrayList<customer>();
ArrayList<Integer> storeRandomNumbers = new ArrayList<>();
int[] splitTheArray =new int[10];
int t=0;
public void buyTickets()
{
customerArray.add(new customer("Jon", 4, 6, 7,8, 7,9));
customerArray.add(new customer("Adams", 4, 4, 4,4, 4,4));
System.out.println(customerArray);
}
public void pickLottery()
{
Random rand1 = new Random();
for(int i = 0; i< 6; i++)
{
storeRandomNumbers.add(rand1.nextInt(8)+1);
}
System.out.println(storeRandomNumbers);
//splitTheArray[t++] = Integer.parseInt(customerArray[0][1]);
System.out.println("Common Items: "+(customerArray.stream().filter(storeRandomNumbers::contains).collect(Collectors.toList())));
}
}
I expected the customerArray numbers would be compared with storeRandomNumbers and give the matching numbers
Add a method in your customer class to check customer's numbers with the list of lottery number. Assuming this method will return "true" if all of customer's numbers are a match for the lottery numbers, "false" otherwise.
public boolean containsLottery(List<Integer> lotteryList)
{
boolean result= false;// default result is false
// implement your solution for finding if the numbers are a match
return result;
}
All you have to change on the main code is this part:
List<customer> CommonList = (customerArray.stream().filter(x-> x.containsLottery(storeRandomNumbers)).collect(Collectors.toList())) ;
I tested it on my version of customer class and this .filter(x-> x.containsLottery(storeRandomNumbers)) part seems to work. Try it and let me know how it goes.

How to sort an array without losing reference to the index thingy?

Okay. I'm effectively a -total- beginner to coding (taken some classes but a slow/dense learner) and the answer is probably ridiculously simple. I have one string array that has names and another that has the scores associated.
names[0] = blinky
scores[0] = 42 (blinky's score)
names[1] = inky
scores[1] = 37 (inky's score)
in the for loop i calls the number (index number? I'm horrible with terms. The only thing that ever seems to make sense is the code itself). Anyway, I want to be able to preserve i.
I want to make a list that puts the names with the scores in order from highest to lowest.
I don't know if using util.Arrays or anything that will automatically sort will help. I believe I'll have to manually have to sort them in order to keep the names and numbers aligned
//Example
String[] names = {"Blinky","Inky","Pinky","Clyde"};
int[] scores = {42,37,67,50};
for (int = 0; i < scores.length; i++){
System.out.println("what do?")
}
How would I go about making a list that puts the names in order? Simpler the better.
I'd be very appreciative of help.
Edit: I'd like to thank all of you for your help! :)
To get the results below, you can try out the following codes.
Unsorted
---------
Blinky, score=42
Inky, score=37
Pinky, score=67
Clyde, score=50
sort by score ascending
Inky, score=37
Blinky, score=42
Clyde, score=50
Pinky, score=67
sort by Name ascending
Blinky, score=42
Clyde, score=50
Inky, score=37
Pinky, score=67
1) create a new class called NameScoreEntity to store both variables together (this way when you sort, both the names and scores are done at the same time)
public class NameScoreEntity {
String name;
int score;
public NameScoreEntity(String name, int score) {
this.name = name;
this.score = score;
}
#Override
public String toString() {
return name + ", score=" + score;
}
}
2) you then create an arrayList of your new class to copy your two arrays into.
String[] names = {"Blinky","Inky","Pinky","Clyde"};
int[] scores = {42,37,67,50};
List<NameScoreEntity> data = new ArrayList<>(); // your data is now stored here
for (int i= 0; i < scores.length; i++){
data.add(new NameScoreEntity(names[i], scores[i]));
}
//print unsorted
System.out.println("Unsorted\n---------");
for (NameScoreEntity e : data) {
System.out.println(e);
}
3) finally, you just use the sort() method that is available in the list to do your sorting.
System.out.println("sort by score ascending");
data.sort(new Comparator<NameScoreEntity>() {
#Override
public int compare(NameScoreEntity o1, NameScoreEntity o2) {
return Integer.compare(o1.score, o2.score); //for descending just swap o1 & o2
}
});
for (NameScoreEntity e : data) {
System.out.println(e);
}
System.out.println("sort by Name ascending");
data.sort(new Comparator<NameScoreEntity>() {
#Override
public int compare(NameScoreEntity o1, NameScoreEntity o2) {
return o1.name.compareTo(o2.name) ;//for descending just swap o1 & o2
}
});
for (NameScoreEntity e : data) {
System.out.println(e);
}
You should use a TreeMap, which will always keep the orders between your scores and match the corresponding String.
// new TreeMap that sorts from highest to lowest
Map<Integer, String> map = new TreeMap<>(Collections.reverseOrder());
Then just put all your values into the Map using the loop you already have:
for(int i = 0; i < scores.length; i++)
map.put(scores[i], names[i]);
And finally you can just print the Map:
System.out.println(map);
Result:
{67=Pinky, 50=Clyde, 42=Blinky, 37=Inky}

Java BubbleSort

I am facing a problem where I need to sort a String array in alphabetical order. I am able to sort one array, but the problem starts when there are 2 more arrays, that correspond to the first array. Each value in each array should be in the same place, to make information not messed up. After sorting array1, it is in alphabetical order, but i don't have any idea how to make values from array2 and array3 change the positions the same like in array1 after sorting is finished.
My code so far is:
public void sort()
{
boolean finish = false;
while(finish == false){
finish = true;
for(int i=0;i<Country.length-1;i++)
{
int num = 0;
if(Country[i] != null && Country[i + 1] != null)
{
String name1=Country[i]; String name2=Country[i+1];
num=name1.compareTo(name2);
}
else if(Country[i] == null && Country[i + 1] == null){
num = 0;
}
else if(Country[i] == null){
num = 1;
}
else {
num = -1;
}
if(num>0)
{
String temp=Country[i];
Country[i]=Country[i+1];
Country[i+1]=temp;
finish=false;
}
}
}
By far the most recommended way is to re-design your program, and arrange all the related items in a single class. This is what objects are for, after all. Then you can make the object Comparable, give it a compareTo method, and sort it.
But if you are really unable to do that, what you should do is, whenever you exchange any two items in your sort array, make sure you exchange the corresponding items in the other arrays.
So, if you have arrays country, capital and headOfState, you will have to write something like:
String temp=country[i];
country[i]=country[i+1];
country[i+1]=temp;
temp=capital[i];
capital[i]=capital[i+1];
capital[i+1]=temp;
temp=headOfState[i];
headOfState[i]=headOfState[i+1];
headOfState[i+1]=temp;
This way, whenever you move anything in your main array, you'll also be moving the respective item in the other arrays, so they will stay together.
But again, it's much more preferred if you re-designed your program.
Also note the Java language conventions - variable names should not start with a capital letter, only type names should.
If you want all the array to be swaped based on the compare you did in the country array. You can just swap more than one array after one compare.
If(array1[i] > array1[i+1]){
Swap(array1[i],array1[i+1)
Swap(array2[i],array2[i+1])
}
By using a swap function, you can make it more simpler to do swaping in much more array.
You have to swap elements in Country and City arrays simultaneously.
public class BubbleSortTmp {
public String[] Country = {"z", "h", "a"};
public int[] City = {3, 2, 1};
public void printCountry() {
for (String s : Country) {
System.out.printf("%s ", s);
}
System.out.println();
}
public void printCity() {
for (int s : City) {
System.out.printf("%s ", s);
}
System.out.println();
}
public void sort() {
for (int outer = Country.length - 1; outer > 0; outer--) {
for (int inner = 0; inner < outer; inner++) {
if (Country[inner].compareTo(Country[inner+1]) > 0) {
swapCountry(inner, inner+1);
swapCity(inner, inner+1);
}
}
}
}
private void swapCountry(int first, int second) {
String tmp = Country[first];
Country[first] = Country[second];
Country[second] = tmp;
}
private void swapCity(int first, int second) {
int tmp = City[first];
City[first] = City[second];
City[second] = tmp;
}
public static void main(String[] args) {
BubbleSortTmp bs = new BubbleSortTmp();
System.out.println("Before: ");
bs.printCountry();
bs.printCity();
bs.sort();
System.out.println("After: ");
bs.printCountry();
bs.printCity();
}
}

Finding duplicate random numbers in an ArrayList

public class LotteryNumbers {
private ArrayList <Integer> numbers;
public LotteryNumbers() {
this.numbers = new ArrayList <Integer> ();
this.drawNumbers();
}
public ArrayList <Integer> numbers() {
return this.numbers;
}
public void drawNumbers() {
Random random = new Random ();
int counter = 0;
while (counter < 7) {
this.numbers.add(random.nextInt(39) + 1);
counter++;
}
}
This is a class used for printing 7 numbers from 1..39.
It does that job but the problem is I want the 7 random numbers to be different.
How do I check if an arrayList contains the same number since it is random?
Thanks for reading.
You could try using the contains() method from the ArrayList numbers:
public void drawNumbers()
{
Random random = new Random();
int counter = 0;
int choice;
while (counter < 7) {
choice = random.nextInt(39) + 1;
if (numbers.contains(choice)) {
continue;
}
numbers.add(choice);
counter++;
}
}
From Java Docs:
public boolean contains(Object o): Returns true if this list contains
the specified element.
So, if the ArrayList already contains the choice (randomly generated), it will continue to the next iteration (counter won't be increased) and choose another random number. If it doesn't contains the choice, it will add it to the array and increase counter.
This can also be done by this way (without using continue)
if (!numbers.contains(choice)) {
numbers.add(choice);
counter++;
}
How do I check if an ArrayList contains the same number since it is random?
Like this (example):
public void drawNumbers() {
Random random = new Random ();
int counter = 0;
while (counter < 7) {
int newNumber = random.nextInt(39) + 1;
if (! numbers.contains(newNumber)) {
this.numbers.add(newNumber);
counter++;
}
}
}
You could use contains as as the earlier responses suggest, however contains on an array list in inefficient with O(n) complexity. One of the comments by #TheLostMind suggest using a Set, the best Set implementation to use in this instance is BitSet, note it does not confirm to the java.util.Set interface specification.
public class LotteryNumbers {
private final int[] numbers = new int[7]
public LotteryNumbers() {
this.drawNumbers();
}
public int[] numbers() {
return this.numbers;
}
public void drawNumbers() {
BitSet selected = new BitSet(40);
Random random = new Random ();
int counter = 0;
while (counter < 7) {
int num = random.nextInt(39) + 1;
if(!selected.get(num)) {
selected.flip(num);
numbers[counter++] = num;
}
}
}
This implementation, tho unlikely, does not guarantee that you will always get a result.
You could also put your numbers in a list and use COllections.shuffle and get the first 7 occurences.
You do not need to check if duplicate...
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
....
Collections.shuffle(list);
loop and get your numbers...
int num = Integer.intValue(list.get(i));

Categories