how to create a Java List of two integers - java

Hello I am new to java and I am trying to create a list like
List<Int, Int> list = new List<Int, Int>();
the first int is the value and the second int is the finished time. I want to be able to read from a file and save in my list, So can I later get the finished time or value list in a sorted way. I am going to ue these two list together so when the first one is sorted the second one also needs to be sorted accordingly.
If I use HashMap I cant add duplicate values, can someone help me please?
I tried with TreeMap but it also didnt work.

You should create a class to wrap your values. Something like:
public class IntPair {
public int value;
public int time;
}
should do. You can then add a constructor, a compare method for sorting, and whatever other functionality you need.
Create the list as follows:
List<IntPair> list = new ArrayList<>();

Using java inbuilt Pair class. ArrayList or any List of pairs can be constructed. you need to import javafx.util.pair for that. Similarly for 3 values. Use java's Triplet class.
eg: Pair p=new Pair(1, 2);
ArrayList or any List of these pairs can be constructed easily now

The 'lazy' way you could create an ArrayList<Integer[]> at each index you add an array of 2 places holding the value and the time ex new Integer[]{val,time} and then you can sort the arraylist using the Collection.sort and with the help of a Comparator
Here is a small example :
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
public class Test {
public static void main(String[] args) {
ArrayList<Integer[]> values = new ArrayList<>();
Random rand = new Random();
// just for testing I add random values but you
// should add your values you read from your file
for (int i = 0; i < 10; i++) {
values.add(new Integer[] { rand.nextInt(100), rand.nextInt(100) });
System.out.println(values.get(i)[0] + "\t" + values.get(i)[1]);
}
// Let's sort our ArrayList looking at the first index of each array
// which holds the value
Collections.sort(values, new Comparator<Integer[]>() {
public int compare(Integer[] array1, Integer[] array2) {
return array1[0].compareTo(array2[0]);
}
});
// Print the results
System.out.println();
System.out.println();
for (int i = 0; i < 10; i++) {
System.out.println(values.get(i)[0] + "\t" + values.get(i)[1]);
}
}
}
Output :
82 21
3 54
60 73
14 35
45 30
16 30
8 19
62 43
67 51
7 34
3 54
7 34
8 19
14 35
16 30
45 30
60 73
62 43
67 51
82 21

Related

Collection Iteration not showing proper values?

I'm iterating through a simple Collection. I populate the Collection with random Integer objects, defined via the following:
Collection<Integer> treeSet = new TreeSet<>();
treeSet = createFilledCollection(10000, treeSet);
printContents(hashSet);
//populate the Collection
private Collection<Integer> createFilledCollection(long size, Collection<Integer> collection){
for(int i = 0 ; i < size; i++) {
Integer integer = (int)(Math.random() * 100);
collection.add(integer);
}
return collection;
}
Then I iterate through the contents of this Collection and print it's contents through the printContents(hashSet);
private void printContents(Collection<Integer> collection) {
StringJoiner joiner = new StringJoiner(",");
for(Integer i : collection) {
if(i > 500)
break;
System.out.println(i);
joiner.add(i.toString());
}
System.out.println(joiner.toString());
}
I'm expecting to see a random assortment of numbers
10 41 2 23 44 65 6... 19 11
(as I add random numbers through the createFilledCollection(Integer size, Collection collection) method. However, I get the following output:
0 1 2 3 4 5 6... 98 99
Why am I not seeing random numbers? (and yes, I checked to make sure I am not printing the iteration point)
That is because you are using TreeSet, The ordering of the elements is maintained by a set using their natural ordering whether or not an explicit comparator is provided.
Change TreeSet to like HashSet and you will get the desired output

How can I sort an ArrayList with Insertion Sort?

I've got an assignment where my teacher is asking us to import a text file with 2043 Euromillions keys with this format:
1987 45 12 14 39 43 48 8 10
1981 23 12 18 22 29 45 10 12
1980 6 29 31 45 46 50 4 8
2018 19 2 4 16 19 50 6 12
1986 23 1 10 33 38 42 7 12
1986 40 18 23 26 27 36 7 12
...
I've imported the file to an ArrayList and I need to use Insertion Sort to sort the keys by date(first number is year and the next following is week) and with the following format:
{1987/45} |12|14|39|43|48| |8|10|
{1981/23} |12|18|22|29|45| |10|12|
...
Any ideas on how to sort the keys by date and store them in an Array or ArrayList?
I've imported the file to an ArrayList but idk if it was a good idea, I tried sorting the ArrayList but with no success.
private static ArrayList<String> ImportedKeys = new ArrayList<String>();
public static void importarChaves() {
String linha;
int year,week,ball1,ball2,ball3,ball4,ball5,star1,star2;
File file=new File("Documento/euromilhoes.txt");
Scanner leitor=null;
try {
leitor = new Scanner(file);
} catch (FileNotFoundException e) {
System.out.println("File not found");
e.printStackTrace();
}
int count = 0;
while(leitor.hasNextLine()){
linha=leitor.nextLine();
// System.out.println(linha);
Scanner lerString=new Scanner(linha);
year=lerString.nextInt();
week=lerString.nextInt();
ball1=lerString.nextInt();
ball2=lerString.nextInt();
ball3=lerString.nextInt();
ball4=lerString.nextInt();
ball5=lerString.nextInt();
star1=lerString.nextInt();
star2=lerString.nextInt();
ImportedKeys.add(linha);
count++;
lerString.close();
}
A few things. First, an Insertion Sort is a very specific type of sort where you sort as you're inserting. That is, at any given time, your array is sorted. When you add the 400th element, it is insert into the correct location.
Here's what I would do. First, I'd start with a much shorter sample file so your output is reasonable. 10 lines.
I would create an object that represents one line, but not as a string, but as an object with the various parts. Remember you can't do a string comparison because week 6 will sort after week 11. So your object might contain a numeric year, numeric week, and then whatever the rest of that stuff is.
Then I would do this: I would write JUST an input method that reads the file and produces an (unsorted) array of your new objects. Test it by reading in your file and printing out the results. This will verify you're reading properly.
Then I would understand a few concepts.
An empty list is sorted.
A list with 1 item is sorted.
If a list is sorted, you can do a binary search on it.
What is a binary search?
class MyArray extends ArrayList<MyObject> {
public int insertionPoint(int year, int month {
return insertionPoint(year, month, 0, length());
}
private int insertionPoint(int year, int month, int low, int high) {
if (low >= high) {
return low;
}
int mid = (low + high) / 2;
MyObject obj = get(mid);
if (obj.year < year || (obj.year == year && obj.month < month)) {
return insertionPoint(year, month, low, mid);
}
return insertionPoint(year, month, mid+1, high);
}
}
This is a binary search. This is a VERY VERY important concept. Your list is sorted, which means you can quickly find an existing object (or where a new object should go) by dividing the list in half. Let's say there are 2000 items. You check the 1000th item. If you are searching for a spot before that (see the if-statement), then. you only have to look in the first half of the list. Otherwise you look in the second half.
Once you have an insertion point, you can simply insert your NEW item into the list at that point. And THAT is an insertion list.
Note: I'm writing the code by hand not in an IDE. It might not be perfect.
All told, when you're done, this SHOULD be fewer than 100 lines of code. That should be enough to define your new object plus define a sorted list that knows how to do an insert, plus the code to test it.
But the trick of an insertion sort:
Keep your array sorted as you go
Understand a binary search
You need to understand recursion. My second method above is highly recursive. It breaks the list down into smaller and smaller pieces until it figures out where your next item should go.
So what you do:
Make your MyObject object (or whatever you call it).
int location = myList.insertLocation(object.year, object.week)
add(location, object)

Java: Sorting an array from least to greatest

This is my first question on the site. I am in a CS class and part of one of my assignments involved sorting the scores column of an array from least to greatest and printing out the array in its new least-to-greatest form. I cannot seem to get the scores from the array to do so, for whatever reason, and I am very confused as to why it will not work. If any of you could help me, that would be awesome. Thanks! Here is the array I am working with. The two columns are the id (on the left) and the score (on the right):
365 265
222 223
306 262
003 559
004 560
203 224
113 243
208 242
213 229
115 257
302 242
223 230
001 599
311 256
323 245
321 245
123 253
104 239
002 513
112 239
207 228
325 246
116 246
218 243
110 238
And here is my code so far:
import java.io.*;
import java.util.*;
public class RankingTestScoresDriver
{
public static void main(String args[])
{
System.out.println("ID Score");
File file = new File("prog408a.dat");
int[] id = new int[24];
int[] score = new int[24];
try
{
Scanner kbReader = new Scanner(file);
while (kbReader.hasNextInt())
{
for (int i = 0; i < 25; i++)
{
id[i] = kbReader.nextInt();
score[i] = kbReader.nextInt();
}
}
}
catch (Exception e)
{
}
//From here down is the part which is giving me trouble.
int max;
max = score[0];
int index;
int maxScoreIndex = 0;
for (int k = 0; k < 25; k++)
{
for (index = 0; index < score.length; index++)
{
if (score[index] > max)
{
max = score[index];
maxScoreIndex = index;
}
}
System.out.println(maxScoreIndex + " " + max);
score[maxScoreIndex] = ((-1)*(max));
}
}
}
Currently it is producing this as the output:
ID Score
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
12 599
The final output should be the scores of the array but in least-to-greatest order.
Any help would be greatly appreciated in helping me fix the bit of code I am struggling on.
You can write a class that implements Comparable to do it simple.
class Score implements Comparable<Score> {
private int id, score;
Score(int id, int score) {
this.id = id;
this.score = score;
}
#override
public int compareTo(Score o) {
return score - o.score;
}
}
then after you create an array of Score, you can use sort() method.
Score[] scores = /* put data */
Arrays.sort(scores);
will work
In the section where you are trying to sort, I'd recommend calling Arrays.sort() on your array like this:
Arrays.sort(score);
Once you have the array sorted, print out each element from the beginning using a loop of some kind:
for(int i = 0; i < 25; i++)
{
System.out.println(i + " " + score[i]);
}
That should do the trick for you. If you don't need a fancy new sorting algorithm, just use one that's already coded for you :)
You need to sort the array. Right now your code doesn't do it, it just keeps track of the biggest value.
I'm assuming you don't have to worry about execution time here. In other words, if the algorithm is going to take a long time to execute for a large input it doesn't matter to your professor.
There are many ways to sort an array. One way to do it called Bubble Sort. It is not very effective but will do the trick for you, and it's probably what your professor wants for now.
The idea is pretty simple: you discover the lowest value you hold on the entire array and swap the value with your current position. Imagine you have the following array:
[2, 4, 3, 5, 1]
Your current index is 0. You're going to go through the entire array to find the lowest value of them all. You will find out that the index 4, that holds the value 1 contains the lowest value. So you swap your current index (index 0, value 2). Now the array looks like this:
[1, 4, 3, 5, 2]
Now you move on to the next index, which is 1. You don't need to look at index 0 anymore since you already found out he is the lowest value and now you want the second lowest value. You do the same thing you did before: find the lowest value from index 1 to index 4 and swap them. You're going to do it until you get to the last index, where, you can guess by now, it will always be the biggest value.
Start by making sure you get the first value right. Once you get it, then move to the loop that iterates through the other values.
Working code : sort a two-dimensional array on column values in java.
Here we are using overloaded sort method in java.util.Arrays class which takes two arguments : the array to sort and a java.util.Comparator object.
import java.util.Arrays;
import java.util.Comparator;
public class SortArray {
Integer array[][] = { { 365, 265 }, { 222, 223 }, { 306, 262 },
{ 003, 559 }, { 004, 560 }, { 203, 224 }, { 113, 243 },
{ 208, 242 }, { 213, 229 }, { 115, 257 }, { 302, 242 },
{ 223, 230 }, { 001, 599 }, { 311, 256 }, { 323, 245 },
{ 321, 245 }, { 123, 253 }, { 104, 239 }, { 002, 513 },
{ 112, 239 }, { 207, 228 }, { 325, 246 }, { 116, 246 },
{ 218, 243 }, { 110, 238 } };
SortArray() {
System.out.println("Before sorting");
// show the contents of array
displayArray();
// sort array on score(second column)
Arrays.sort(array, new Comparator<Integer[]>() {
#Override
public int compare(Integer[] o1, Integer[] o2) {
Integer v1 = o1[1];
Integer v2 = o2[1];
// reverse sort on quantity
return v1.compareTo(v2);
}
});
// display array after sort
System.out.println("After sorting on score in ascending order");
displayArray();
}
public void displayArray() {
System.out.println("-------------------------------------");
System.out.println(" Index \t\t score");
for (int i = 0; i < array.length; i++) {
Integer[] sorted = array[i];
System.out.println(sorted[0] + "\t\t" + sorted[1]);
}
System.out.println("-------------------------------------");
}
public static void main(String[] args) {
new SortArray();
}
}
Explanation
A two dimensional array named array is created and initialized with default values.
First column of the array consists of Index values and second column is its Score.
For sorting the array, sort method of java.util.Arrays is used which takes 2 arguments : the array to be sorted and a java.util.Comparator object.
We pass an anonymous Comparator object(anonymous object means an object which has no name and which is created at its place of use only).
As 2d array in java is an array of arrays, thus, for sorting a 2d array on a column, we have to sort an integer array, therefore the generic type of this Comparator object should be Integer[ ].
Inside Comparator object, we implement its compare method which takes two objects of Integer[ ] type. These Integer objects represent the arrays to be compared.
For sorting the array on second column(score), the values at index 1 of the Integer[ ] objects are retrieved and compared.
Also read about Comparators and sort()
public static <T> void sort(T[] a,
Comparator<? super T> c)
Sorts the specified array of objects according to the order induced by the specified comparator. All elements in the array must be mutually comparable by the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the array).
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered. If the input array is nearly sorted, the implementation requires approximately n comparisons. Temporary storage requirements vary from a small constant for nearly sorted input arrays to n/2 object references for randomly ordered input arrays.
The implementation takes equal advantage of ascending and descending order in its input array, and can take advantage of ascending and descending order in different parts of the the same input array. It is well-suited to merging two or more sorted arrays: simply concatenate the arrays and sort the resulting array.
The implementation was adapted from Tim Peters's list sort for Python ( TimSort). It uses techiques from Peter McIlroy's "Optimistic Sorting and Information Theoretic Complexity", in Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, January 1993.
Parameters:
a - the array to be sorted
c - the comparator to determine the order of the array. A null value indicates that the elements' natural ordering should be used.

Java TreeSet BigO complexity seems off

I believe that Java TreeSet has a balanced tree implementation which can perform tree sort(a lot like the quick sort) quickly. My recently-encountered problem shows that it seems to be performing more comparisons that I expect.
Does every balanced tree perform like Java's TreeSet on sort(insert), or is my performance testing approach wrong?
My code:
package expri.johnny.treeSortCompTimes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetCompTimeTest {
public static void main(String[] args) {
int size=1000;
ArrayList<Integer> ay =new ArrayList<>(size);
int treeHeight = (int) (Math.log (size)/Math.log (2));
System.out.println("tree height: "+treeHeight);
System.out.println("when size is "+ size + ",i expected compare tmies are: "+((treeHeight+1)*treeHeight/2));
for(int i =0,l=size-1;i<=l;i++){
ay.add(i);
}
Collections.shuffle(ay);
System.out.println(ay);
CountComp cc =new CountComp();
TreeSet<Integer> ts =new TreeSet<>(cc);
ts.addAll(ay);
cc.speakCount();
}
private static class CountComp implements Comparator<Integer>{
int counter =0;
#Override
public int compare(Integer o1, Integer o2) {
this.counter++;
int df = o1-o2;
if(df>0){
return 1;
}else if(df==0){
return 0;
}else{
return -1;
}
}
public void speakCount(){
System.out.println("total compared times: "+this.counter);
//when size is 100,i expected compare tmies are: 21
//total compared times: 545
//when size is 1000,i expected compare tmies are: 45
//however, the real total compared times: 8783
}
}
}
well , that is what is in my mind before:
10 compares for add
10 compares for add
10 compares for add
10 compares for add
10 compares for add
10 ...
10
10
10
10
10
10 -997th , what i thought was 7
10 -998th , what i thought was 8
10 - 999th , what i thought was 9
10 - 1000th , what i thought was 10
8547
i make big laughing material this time , hahaha!
The depth of the tree is dynamic as items are added. To estimate the number of comparisons that will be made, iterate over the size of elements to be added and calculate the number of comparisons that will be made for each element based upon the size of the tree at that time.
int sum = 0;
for(int i = 1; i <= size; i++){
sum += (int)Math.ceil(Math.log(i)/Math.log(2));
}
System.out.println(sum);
Which yields 8987 for 1000 elements.
You are correct when assume that insert will use log(n) comparison.
But you insert n elements that give us n*log(n) comparison.
For 1000 elements it give us 9965 comparison.
n here is total amount of elements.
Your formula is totally wrong and I don't know where you got it.

java random generator without repeat

Im trying to generate a 2d array using a random generator. basically, each column should contain a random value between 1-50 that is not repeated but the problem is, I can't get a repeat value on the same row, or any other row or column in the program. In other words, each I integer should only display once. My objects were created via linked list and I will probably integrate the algorthim in there once I figure it out but for now, heres what I did.
int[] array = new int[50];
for(int i=1;i<=9;i++)
{
int[] grades = new int[5];
for(int j=0;j<=4;j++)
{
int unique = gen.nextInt(50)+1;
grades[j] = unique;
}
list.add(new Student(i, grades));
}
System.out.println(list);
My output:
Student1: 20 49 45 16 13
Student2: 28 10 11 30 6
Student3: 13 25 37 31 49
Student4: 8 23 8 12 32
Student5: 22 18 35 2 7
Student6: 35 8 16 23 36
Student7: 35 3 15 42 2
Student8: 43 12 44 2 35
Student9: 12 21 36 23 12
So my issue is this. How can I implement the random gen without repeating values. Normally I would try a collection list by now, but I'm trying to do this using java.util.Random Personally, I would do this a different way but I'm instructed. Thank you
Here's what I would do:
Take an ArrayList of numbers 1-50, then use Collections.shuffle on the list.
You could check if the number is unique before accepting it. For example you could try something like the following:
int count=0;
List<Integer> list=new ArrayList<Integer>();
while(count<50){
int num=random.nextInt(50);
if(!list.contains(num)){
list.add(num);
++count;
}
}

Categories