deleting duplicate objects from an arraylist - java

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'}}

Related

Spark dataset Combine multiple rows

This is my dataset,
Name Group Age
A [123] 10
B. [123,456] 20
C. [456,789] 30
D. [900] 40
E. [800,900] 50
F. [1000] 60
Now I want to merge Group such that, the result looks like
Name Group Age
A,B,C [123,456,789] 10,20,30
D,E [900,800] 40,50
F. [1000] 60
I tried arrays contains but that is not giving me what I want. I tried self join too. Anyone can help with a java solution.
Edit:
I found ReduceFunction which can do something similar.
dataset.reduce(new ReduceFunction<Grouped>(){
private static final long serialVersionUID = 8289076985320745158L;
#Override
public Grouped call(final Grouped v1, final Grouped v2) {
if (!Collections.disjoint(v1.getGroup(), (v2.getGroup())))
{
v1.getAge().addAll(v2.getAge());
v1.getGroup().addAll(v2.getGroup());
v1.getName().addAll(v2.getName());
}
}
}
But how to do this for all rows???
This is able to give me first 2 rows reduced to :
Name Group Age
A,B [123,456] 10,20

Managing java list object and iterating them

I have a list which is a java object like below.
public class TaxIdentifier {
public String id;
public String gender;
public String childId;
public String grade,
public String isProcessed;
////...///
getters and setters
///....///
}
Records in DB looks like below,
id gender childId grader isProcessed
11 M 111 3 Y
12 M 121 4 Y
11 M 131 2 Y
13 M 141 5 Y
14 M 151 1 Y
15 M 161 6 Y
List<TaxIdentifier> taxIdentifierList = new ArrayList<TaxIdentifier>();
for (TaxIdentifier taxIdentifier : taxIdentifierList) {
}
while I process for loop and get the id = 11, i have to check if there are other records with id = 11 and process them together and do a DB operation and then take the next record say in this case 12 and see if there are other records with id = 12 and so on.
One option is i get the id and query the DB to return all id = 11 and so on.
But this is too much back and forth with the DB.
What is the best way to do the same in java? Please advice.
If you anyway need to process all the records in the corresponding database table - you should retrieve all of them in 1 database roundtrip.
After that, you can collect all your TaxIdentifier records in dictionary data structure and process in whatever way you want.
The brief example may look like this:
Map<String, List<TaxIdentifier>> result = repositoty.findAll().stream().collect(Collectors.groupingBy(TaxIdentifier::getId));
Here all the TaxIdentifier records are grouped by TaxIdentifier's id (all the records with id equals "11") can be retrieved and processed this way:
List<TaxIdentifier> taxIdentifiersWithId11 = result.get("11");
I would leverage the power of your database. When you query, you should order your query by id in ascending order. Not sure which database you are using but I would do:
SELECT * FROM MY_DATABASE WHERE IS_PROCESSED = 'N' ORDER BY ID ASC;
That takes the load of sorting it off of your application and onto your database. Then your query returns unprocessed records with the lowest id's on top. Then just sequentially work through them in order.

Summarizing expense by customer number in Java

I want to code the following in Java.
I have the following customer file.
Name acct spending
BigGuy a1 30
BigGuy a2 40
smallGuy a1 300
smallGuy a2 400
smallGuy a3 400
AMR a1 300
AMR a2 400
I need to read the above file and calculate the total for each customer to produce the following.
BigGuy 70
SmallGuy 1100
AMR 700
F = open('spendFile.txt', "r")
arr = [];
for c in F.readlines()[0].split(): #this turns the file into a string and creates a list of each word
arr.append(c)
people = []
amount = []
for i in range(0,len(arr)/3):
name = arr[i*3]
a = arr[i*3+2]
if(name not in people):
people.append(name)
amount.append(int(a))
else:
index = people.index(name)
old = amount[index]
new = old+int(a)
amount[index] = new
for i in range(0,len(people)):
print(people[i]+" "+str(amount[i]))
I put the string you mentioned early in your post into a text file called 'spendFile.txt'. This then reads this and places the string into an array where each entry is a single word. I then iterate over this and grab the name with the corresponding amount. I check these values against the current list of people and amounts and finally print the total amount corresponding with each name. Let me know if you have any questions.
EDIT:
I did not notice that your original file had the first line of 'Name acct spending' and my program does not account for that. So you'll have to get rid of this line when testing and then programmatically throw it out when actually implementing this.

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.

Sort an String-Array in the right order

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.

Categories

Resources