Sort an String-Array in the right order - java

I have tried to sort my array in the right order. I have stored 3 variables (1 int, 1 String, 1 float) in one field of the array. I have tried to use the native sort method, but my output is not sorted the right way:
[1 ,Agavendicksaft ,0.180
, 1 ,Agavendicksaft ,0.284
, 100 ,Röstzwiebel ,0.057
, 103 ,Salz fein ,6.220
, 103 ,Salz fein ,6.452
, 104 ,Salz grob ,0.490
, 114 ,Sesam ,0.735
, 114 ,Sesam ,1.742
, 115 ,Soja Granulat ,43.788
, 116 ,Sonnenblumenkerne ,0.267
, 116 ,Sonnenblumenkerne ,3.636
, 12 ,BAS hell ,0.975
, 12 ,BAS hell ,6.996
, 139 ,Vanille Aroma ,0.068
, 140 ,Weizenmehl Type W1600 ,1.163
, 140 ,Weizenmehl Type W1600 ,1.927
, 141 ,Weizenmehl Type W700 ,138.127
, 141 ,Weizenmehl Type W700 ,45.158
, 142 ,Walnüsse ,0.228
, 144 ,Wiechert Glutenfei ,1.160
, 145 ,Wienerwurst Stange ,0.100
, 150 ,Zitronen Aroma ,0.068
, 151 ,Zucker Normalkristall ,1.039
, 153 ,Wasser ,167.202
, 21 ,Dinkel Flocken ,0.347
, 24 ,Eier ganz ,0.453
, 26 ,Eigelb ProOvo ,0.365
, 29 ,Fenchel ganz ,0.105
, 36 ,Hafer ganz ,3.078
, 47 ,Hirse ganz ,0.133
, 49 ,Honig ,0.186]
So I have two questions:
How could I sort the array right?
How could I combine multiple entries to one entrie? f.e. not 140, 1.163 140, 1.927 => 140, 3,09 (I cannot do that earlier in my code because the array is a combination of 3 sql-result-arrays)
Here is my code:
s = Results2String(resultSet);
splitResult = s.split("/");
System.out.println(s);
s = null;
s = Results2String(resultSet2);
splitResult2 = s.split("/");
System.out.println(s);
s = null;
s = Results2String(resultSet3);
splitResult3 = s.split("/");
System.out.println(s);
System.out.println(splitResult3[0]);
preResult = new String[splitResult.length + splitResult2.length];
System.arraycopy(splitResult, 0, preResult, 0, splitResult.length);
System.arraycopy(splitResult2, 0, preResult, splitResult.length, splitResult2.length);
System.out.println(Arrays.toString(preResult));
result = new String[splitResult.length + splitResult2.length + splitResult3.length];
System.arraycopy(preResult, 0, result, 0, preResult.length);
System.arraycopy(splitResult3, 0, result, preResult.length, splitResult3.length);
Arrays.sort(result);
System.out.println(Arrays.toString(result));

I assume that one of each int, String and float belong together.
So you should put them in one class and implement Comparable (documentation):
public class Food implements Comparable<Food> {
private int id;
private String name;
private float score; // or maybe kcal... ?
public Food(int id, String name, float score) {
this.id = id;
this.name = name;
this.score = score;
}
#Override
public int compareTo(Food other) {
return id - other.getId();
// use the following if you want to sort by name instead
// return name.compareTo(other.getName());
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
Then you can sort an array of Foods....
How to use
I'm still not sure what your resultSets are (and why you have three of them) but I assume that they are ResultSets from a database query. Furthermore I assume that the id-name-score-combinations are actually rows in a database.
You could then go through those ResultSets and put the values of each row in a Food object:
ResultSet resultSet; // filled somewhere else
List<Food> food = new ArrayList<Food>();
while (resultSet.next()) {
int id = resultSet.getInt(0); // assuming the ids are in the first column
String name = resultSet.getString(1); // assuming the names are in the second column
float score = resultSet.getFloat(2); // assuming the scores are in the third column
food.add(new Food(id, name, score));
}
Collections.sort(food);
I hope this helps...
However, if your resultSets are really ResultSets from a database query, then you should probably sort your values in your SQL query with ORDER BY...

You need to write a comparator method and use the Collections.sort(List<T>, Comparator<? super T> method. Here is a link to the Collections java doc online.
inside your comparator, split the line into 3 parts (int, string, float) and compare them as you see fit.

Create an class with those three attributes.
public class Example{
private int field1;
private String field2;
private double field3;
.....
}
Fill you array with Objects made of this class then sort your array with a Comparator for this class that compares the String.

Related

deleting duplicate objects from an arraylist

I have an array list consisting of objects defined in the class Result(date, name, grade). I have managed to sort the dataset. However I want there to be no duplicates, only the object with that has highest grade attribute should be left. I have tried several codes but it gets me no where.
The data looks as following now,
DATE NAME GRADE
0612 AA BB 15
0713 AA BB 12
0613 CD E 7
0327 KA BC 23
0903 KA BC 15
But i want it to look like this
0612 AA BB 15
0613 CD E 7
0327 KA BC 23
Result class defined as below
Result(int date,String name, String grade){
this.date=date;
this.name=first;
this.grade=grade;
}
for (Result element:info) {
if (!newList.contains(element.name)) {
newList.add(element);
}
}
for(Result st:newList){
System.out.println(st.date+" "+st.name+" " + st.grade);
}
}
}
I have done this, so far. However it does not give me the wanted output.
You can take advantage of Java streams API. Grouping the values by name and getting the highest grade:
Map<String, Result> map = newSet.stream()
.collect(Collectors.toMap(Result::getName, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Result::getGrade))));
I've tested it using the following:
Result r1 = new Result(1, "Emmanuel", "14");
Result r2 = new Result(2, "Emmanuel", "15");
And the result is:
{Emmanuel=Result{date=2, name='Emmanuel', grade='15'}}

I need to convert the Arraylist of hashmap to DTO below in Java

I want to covert the Linkedhashmap to the below DTO object
INPUT HASHMAP:[{
param1 = Hello,
Year 1 Value = 600,
Year 2 Value = 600,
},
{
param2 = Hello,
Year 1 Result = 500,
Year 2 Result = 700,
}]
Desire Output DTO
private String paramname;
//paramname will have param1.param2 names;
private List<ResultDto> data;
List<ResultDto>
private Long year;
private long value;
//year 1 will have value respectively
please check the loops which will work here or any better performance iterations .
I tried the many approach through for loop.

How to retrieve previous values from HashMap?

I have the following code where I'm reading from a text file. The text file i as follows:
111 Laptop 500 10
222 Mobile 120 8
333 Notebook 4 100
444 Chocolates 3 50
555 Guitar 199 5
666 LenovoLaptop 470 10
777 HPLaptop 450 10
888 SonyVAIO 525 5
If the user enters ID as 111, the following should be the output:
111 Laptop 500 10
666 LenovoLaptop 470 10
777 HPLaptop 450 10
888 SonyVAIO 525 5
I'm storing the the contents of the text file in a HashMap. Here is the code:
public void comparableItems(String ID)
{
File f = new File("C://Class/items.txt");
HashMap<String, Item> map = new HashMap<String, Item>();
try
{
Scanner scan = new Scanner(f);
while(scan.hasNext())
{
String line = scan.nextLine();
String temp[] = line.split(" ");
Item it = new Item(temp[0], temp[1], Double.parseDouble(temp[2]), Integer.parseInt(temp[3]));
map.put(it.itemID, it);
}
if(map.containsKey(ID))
{
Item item = map.get(ID);
if(item.price>=item.price+100 && item.price<=item.price-100)
{
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Here is the Item class:
public class Item
{
String itemID;
String itemName;
double price;
int quantity;
public Item(String itemID, String itemName, double price, int quantity)
{
this.itemID = itemID;
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
public void printItemDetails()
{
System.out.println("ID\tItemName\tUnitPrice\tQuantity");
System.out.println("===================================================");
System.out.println(this.itemID+ "\t" +this.itemName+ "\t" +this.price+ "\t"+this.quantity);
}
}
How do I get the desired output? I'm in the learning stages of Java Collections. So please bear with me.
Can someone help me here?
Thanks!
Your Map isn't doing you much good. Since you know what reference item ID you're looking for before you even parse the file, you could just capture that item when (and if) you see it during the parse. You do need some kind of collection to hold all the other items, but a List would be a better choice for this particular task.
In any case, the thrust of your question seems to be about examining all the other items you parse from the file. For this, you want to iterate over the Map's values() view (and to get your comparisons right):
for (Item otherItem : map.values()) {
if((otherItem.price <= item.price + 100)
&& (otherItem.price >= item.price - 100)) {
otherItem.printItemDetails();
}
}
If you collected the items in a List instead of a Map, then you would replace map.values() in the above with just list (or whatever name you use for the List).
For what you say you want (items with prices near the desired item), a HashMap isn't an efficient datastore.
However, since it sounds like this is your homework, once you use map.get("111") to get your laptop, get the price P, and then iterate over the hashmap to get any item whose price is within your desired delta of P. The Collections tutorial tells you how to iterate over a collection.

Sorting groups of values according to total value

I'm writing an app for evaluating points and ranks of a competition and I have this specific problem:
I have groups of teams, each consists of 4 competitors. Each member of team has some penalty points which is then summed up for a whole team. For example like this:
Team1 name, discipline1, discipline2, discipline3, total, RANK
first xxxxxxxx, 10 , 20 , 30 , 60 , 2
second xxxxxxxx, 10 , 20 , 30 , 60 , 2
third xxxxxxxx, 10 , 20 , 30 , 60 , 2
fourth xxxxxxxx, 10 , 20 , 30 , 60 , 2
total 40 , 80 , 120 , 240
Team2 name, discipline1, discipline2, discipline3, total, RANK
first xxxxxxxx, 10 , 10 , 30 , 50 , 1
second xxxxxxxx, 10 , 10 , 30 , 50 , 1
third xxxxxxxx, 10 , 10 , 30 , 50 , 1
fourth xxxxxxxx, 10 , 10 , 30 , 50 , 1
total 40 , 40 , 120 , 200
and so on...
I need to sort these groups of teams according to the total penalty points in total/total cell. Any hints how to effectively solve this? This is my first app in java so I will appreciate any help.
You should use List to store Team class instances, so you can sort them easily. Look for examples with Comparator and Comparable interfaces. Team class will contain teamMembers, that store TeamMember class instance with penalties, and TeamMember should have getter method for penalties sum. This method will be called from team instance, to account team penalties sum. So in your comparison you will be able to call team method, that returns sum of team members penalties.
As long as I don't know if teams or competitors will have more than the example data, and this is one of your first Java apps I would recommend approach this problem usin simple objects to start with OOP.
Create two classes: Team and Competitor.
Team class must have a List<Competitor>, name, and a method to calculate the penalty:
Team.java
public class Team {
private String name;
private List<Competitor> competitors;
// create getters and setters for name and competitors....
// constructor:
public Team(String name) {
this.name = name;
}
public int getScore() {
int totalScore;
// sum all scores of the team using Competitor.getScore()
for (Competitor c : competitors) {
totalScore += c.getScore();
}
return totalScore;
}
}
Competitor class must have a List<Integer>, name, surname and a method to calculate the score of the entity:
Competitor.java
public class Competitor {
private String name;
private String surname;
// you can also create a Discipline class... but
// I think is not mandatory in this case
private List<Integer> punctuations; // store the punctuations
// create getters and setters for name, surname and punctuations
public int getScore() {
int totalScore = 0;
// sum all scores of the competitor
for (Integer punctuation : punctuations) {
totalScore += punctuation;
}
return totalScore;
}
}
Then you just have to process it in your Main depending of your number of teams and competitions:
public static void main(String[] args) {
// create teams
Team t1 = new Team("T1");
List<Competitors> t1Competitors = new ArrayList<>();
// create competitors
Competitor c1 = new Competitor("John", "Doe");
// fill competitors info
List<Integer> c1Punctuation = new ArrayList<>();
c1Punctuation.add("10");
c1Punctuation.add("20");
c1Punctuation.add("30");
c1.setPunctuation(c1Punctuation);
// put competitors into teams
t1Competitors.add(c1);
t1.setCompetitors(t1Competitors);
// get team punctuations
int t1Score = t1.getScore();
// repeat and compare t1Score and t2Score and so on...
}
I have written a program check this out. It sorts the teams based on the total penalty points.
class Player
class Player{
String name;
Integer d1;
Integer d2;
Integer d3;
Integer d4;
Integer total;
Integer Rank;
//Getters Setters
class Team
public class Team {
ArrayList<Player> player;
Integer teamTotal;
public ArrayList<Player> getPlayer() {
return player;
}
public void setPlayer(ArrayList<Player> player) {
this.player = player;
}
public Integer getTeamTotal() {
return teamTotal;
}
public void setTeamTotal(ArrayList<Player> player) {
int tmpTeamTotal=0;
for (Player p : player) {
tmpTeamTotal += p.getTotal();
}
System.out.println(tmpTeamTotal);
teamTotal=tmpTeamTotal;
}
public static Comparator<Team> totalComparator = new Comparator<Team>() {
public int compare(Team tOne, Team tTwo) {
return (tOne.getTeamTotal() - tTwo.getTeamTotal());
}
};
#Override
public String toString()
{
return String.valueOf(this.getTeamTotal());
}
}
Client class
public class Client {
public static void main(String[] args) {
Player pOne = new Player();
pOne.setD1(10);
pOne.setD2(20);
pOne.setD3(30);
pOne.setD4(60);
pOne.setRank(2);
pOne.setName("ABD");
pOne.setTotal(60);
Player pTwo=new Player();
pTwo.setD1(20);
pTwo.setD2(20);
pTwo.setD3(40);
pTwo.setD4(70);
pTwo.setRank(2);
pTwo.setName("SPC");
pTwo.setTotal(60);
ArrayList<Player> playerListOne = new ArrayList<Player>();
playerListOne.add(pOne);
playerListOne.add(pTwo);
Player pTOne = new Player();
pTOne.setD1(10);
pTOne.setD2(70);
pTOne.setD3(30);
pTOne.setD4(90);
pTOne.setRank(2);
pTOne.setName("ABD");
pTOne.setTotal(60);
Player pTTwo=new Player();
pTTwo.setD1(20);
pTTwo.setD2(20);
pTTwo.setD3(40);
pTTwo.setD4(60);
pTTwo.setRank(2);
pTTwo.setName("SPC");
pTTwo.setTotal(80);
ArrayList<Player> playerListTwo = new ArrayList<Player>();
playerListTwo.add(pTOne);
playerListTwo.add(pTTwo);
Team one=new Team();
one.setPlayer(playerListOne);
one.setTeamTotal(playerListOne);
Team two=new Team();
two.setPlayer(playerListTwo);
two.setTeamTotal(playerListTwo);
ArrayList<Team> team=new ArrayList<Team>();
team.add(one);
team.add(two);
Collections.sort(team, Team.totalComparator);
System.out.println(team);
}
}
As per the data input First team total penalty point:120
Second team total penalty point: 140
Program output: [120, 140]

Java Sorting a 2D String Array not working anymore

Ok so i am working on a way to sort a 2D array, one of the dimensions having a string then the other having an int (Stored as a string for convenience sake) I had looked everywhere for a solution on how to sort the arrays in a way that the data from firstArray[1] is moved at the same time (its index's are a child to the movement of:) as firstArray[0]
This effect was achieved by using this
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
Now i am having troubles with the thing. I will step through the code here and please if you can find a problem with it do tell.
First off i have the array:
String[][] fps = new String[2][15];
Arrays.fill(fps[0], "empty");
Arrays.fill(fps[1], "0");
Second i fill the array with some things that the other part of the program gives me, for this example ill use garbage values:
fps[0][0] = "Java";
fps[1][0] = "1";
fps[0][1] = "C++";
fps[1][1] = "14";
fps[0][2] = "C#";
fps[1][2] = "21";
fps[0][3] = "Python";
fps[1][3] = "9001";
Now is where i would call the above sorting command (Note that these values do not completly fill the array, there are some bins where there is no new data.)
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
Now we have the array sorted and i want to search the 2D array for a value, so i use the Arrays.search to find which bin the query is at.
int searchIndex = Arrays.binarySearch(fps[0], "Java");
System.out.println(searchIndex);
So that is the code, and i think i have isolated the problem to being that the sorting part is not working correctly. If any of you have any more questions please post them in the comments. Likewise if you have a possible solution to this puzzling problem, I would love to hear of it!
PS: Just to be clear I had this working, then i shutdown my lappy and next time i booted (and since then) it has not worked.
PPS: As requested the outputs:
Current output:
-16
FPS:
0 ---- No FPS For you!
1 ---- Only one FPS
2 ---- Only two FPS
3 ---- Only three FPS
4 ---- Only four FPS
5 ---- Only five FPS
6 ---- Only six FPS
7 ---- Only seven FPS
8 ---- Only eight FPS
9 ---- Only nine FPS
1 ---- Blah!
Expected/Hoped Output:
-16
FPS:
1 ---- Blah!
0 ---- No FPS For you!
8 ---- Only eight FPS
5 ---- Only five FPS
4 ---- Only four FPS
9 ---- Only nine FPS
1 ---- Only one FPS
7 ---- Only seven FPS
6 ---- Only six FPS
3 ---- Only three FPS
2 ---- Only two FPS
PPPS: If you would like to see the code that i am working with currently:
import java.util.*;
public class Test
{
public static void main (String [] args)
{
String[][] fps = new String[2][15];
Arrays.fill(fps[0], "empty");//Fill up all the spaces so the sort and the search dont crap out
Arrays.fill(fps[1], "0");
//fps[ROW][COLOUMN] = Value + "";
//fps[ROW][COLOUMN] = Value Instances + "";
fps[0][0] = "No FPS For you!";
fps[1][0] = 0 + "";
fps[0][1] = "Only one FPS";
fps[1][1] = 1 + "";
fps[0][2] = "Only two FPS";
fps[1][2] = 2 + "";
fps[0][3] = "Only three FPS";
fps[1][3] = 3 + "";
fps[0][4] = "Only four FPS";
fps[1][4] = 4 + "";
fps[0][5] = "Only five FPS";
fps[1][5] = 5 + "";
fps[0][6] = "Only six FPS";
fps[1][6] = 6 + "";
fps[0][7] = "Only seven FPS";
fps[1][7] = 7 + "";
fps[0][8] = "Only eight FPS";
fps[1][8] = 8 + "";
fps[0][9] = "Only nine FPS";
fps[1][9] = 9 + "";
/* FUMBLE WITH ARRAY AFTER THIS LINE ONLY!*/
//Things to have inputed into the method:
//currentValue (from the line)
//currentVariable (so we know what the name of the array we're dealing with is named)
String currentValue = "Blah!"; //This is the value that will be searched for in the array, if found its child int is incremented by one, if not found it is added to the array.
//Do a binary sort then search in the fps[0] side of things, makesure that the [1] are carried with the [0] changes.
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
int searchIndex = Arrays.binarySearch(fps[0], currentValue); //Get the index of the current search value
System.out.println(searchIndex); // <-- Returns a neg number each time which shows that the sorting is not working correctly, and therefore the search is being thrown off... need to somehow fix.
if(searchIndex >= 0)// If the value is found
{
fps[0][searchIndex] = (Integer.parseInt(fps[0][searchIndex]) + 1) + ""; //Add one instance to the value
} //end if
else //Otherwise find the next open value spot and change it to the current search query (and assign its instances to 1
{
for(int i = 0; i < fps[1].length ; i++)
{
if(fps[1][i].equals("empty"))
{
fps[1][i] = currentValue;
fps[0][i] = 1 + "";
i = fps[1].length; //force the for loop to exit
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
}); //end Arrays.sort
}//end if
}//end for
}//end else
//... Print array in rectangular form
System.out.println("FPS:");
for (int i =0; (!(fps[1][i].equals("empty")) ) ; i++)
{
System.out.println("\t" + fps[0][i] + " ---- " + fps[1][i] );
}//end for
}//end main
}//end class
I believe you have your indexes backwards. You are sorting fps. fps has only 2 elements which are being sorted. I believe you are trying to sort the 15 elements. If you reverse your indexes I believe you will get the desired sorting.
String[][] fps = new String[15][2];
You might consider an array of objects rather than a 2d array in this case. It seems to be a more logical structure and would avoid this type of confusion.
In addition to the problem pointed out in this Answer, there is a problem in this:
int searchIndex = Arrays.binarySearch(fps[0], "Java");
Since you sorted using a custom comparator, you need to use the same custom comparator to do the binary search. Use binarySearch(T[] a, T key, Comparator<? super T> c). (If you use the 2-arg version, you should get an exception because String[] doesn't implement Comparable.)
do you have any resources about the objects (when used in a similar instance to this
See: Sorting using Comparator- Descending order (User defined classes) for an example of how to do this when using a custom object.
one of the dimensions having a string then the other having an int (Stored as a string for convenience sake)
Its not convenient, since sorting a String representation of a number is different than sorting a number. Using a custom object will allow you to store the data properly so you can have a proper sort.

Categories

Resources