parsing a csv file using java - java

I'm a beginner when it comes to Java and I'm trying to pull these values vertically and store them in a data type with their reference. So "A" would have 1,8,7,6 mapped to it and the dates in front would be excluded as well. The csv file is below.
10/1/14, A,B,C,D,E,F,G,H
10/2/14, 1,2,3,4,5,6,7,8
10/3/14, 8,1,2,3,4,5,6,7
10/4/14, 7,8,1,2,3,4,5,6
10/5/14, 6,7,8,1,2,3,4,5
Here is my code. So far I've been able to grab the rows individually, but I'm I don't know how to add them to a data structure. This would return >> C3218
class Main {
public static void main(String[] args) {
Read r = new Read();
r.openFile();
r.readFile();
r.closeFile();
}
}
import java.io.*;
import java.util.*;
public class Read {
private Scanner x;
public void openFile() {
try {
x = new Scanner(new File("test.csv"));
}
catch(Exception e){
System.out.println("could not find file");
}
}
public void readFile() {
while(x.hasNext()){
String a = x.next();
String[] values = a.split(",");
System.out.printf(values[3]); // gets line
}
}
public void closeFile() {
x.close();
}
}

Java is an Object Oriented programming language. I'm going to assume that what you call "data structures" are Objects in Java parlance. For example (and these are just examples, not something you specifically could use for your situation), if I want to represent a person, I might have something like this
public interface Person{
String getName();
Date getBirthDate();
}
public class GenericPerson implements Person{
private final String name;
private final Date bdate;
public GenericPerson(String fullName, Date birthdate){
name = fullName;
bdate = birthdate;
}
#Override
public String getName() {
return name;
}
#Override
public Date getBirthDate() {
return bdate;
}
}
Pretty sparse, but I'm just trying to show some basic concepts.
You asked
I don't know how to add them to a data structure.
In my example, you would instantiate a GenericPerson
Person p = new GenericPerson(name,date);
Of course, you'll need the name and date variables. That's where the parsing the file comes in. So if I had a file of the form
George Costanza,5/4/1956
Cosmo Kramer,12/12/1960
Jerry Seinfeld,1/2/1959
Then in my code to parse the file I might have
String line = scanner.next();
String[] values = line.split(",");
Person p = new GenericPerson(values[0],getDateFormatter().parse(values[1]));
So you create your Object type, defining what fields you want it to have. And then populate them via a constructor or setter methods. An example of setter methods would be if I modified the GenericPerson like this
public class GenericPerson implements Person{
private String name;
private Date bdate;
public void setName(String n){
name = n;
}
public void setBirthDate(Date d){
bdate = d;
}
#Override
public String getName() {
return name;
}
#Override
public Date getBirthDate() {
return bdate;
}
}
Now I would need to call those to set the values in the Object.
For your case, you'll need to define some Object type that the data is meant to define. The type will have fields like the GenericPerson and you need to have setter methods or a constructor that takes arguments corresponding to the fields.
I highly recommend following the online tutorial for java beginners.

It took me 30 minutes just to get your code to compile and run correctly.
I used a List of a Column class that I created. The Column class contains the name of the column and the values in that CSV column.
The test.csv file is in the same directory as the Java class.
Here's the results.
A: 1, 8, 7, 6
B: 2, 1, 8, 7
C: 3, 2, 1, 8
D: 4, 3, 2, 1
E: 5, 4, 3, 2
F: 6, 5, 4, 3
G: 7, 6, 5, 4
H: 8, 7, 6, 5
And here's the code.
package com.ggl.testing;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CSVColumns implements Runnable {
public static void main(String[] args) {
new CSVColumns().run();
}
#Override
public void run() {
Scanner scanner = openFile();
if (scanner != null) {
readFile(scanner);
closeFile(scanner);
}
}
private Scanner openFile() {
String fileString = "test.csv";
return new Scanner(getClass().getResourceAsStream(fileString));
}
private void readFile(Scanner scanner) {
List<Column> columnList = new ArrayList<>();
String a = scanner.nextLine();
a = a.replace(" ", "");
String[] values = a.split(",");
for (int i = 1; i < values.length; i++) {
Column column = new Column(values[i]);
columnList.add(column);
}
while (scanner.hasNext()) {
a = scanner.nextLine();
a = a.replace(" ", "");
values = a.split(",");
for (int i = 0; i < columnList.size(); i++) {
Column column = columnList.get(i);
column.addValue(Integer.valueOf(values[i + 1]));
}
}
for (int i = 0; i < columnList.size(); i++) {
System.out.println(columnList.get(i));
}
}
private void closeFile(Scanner scanner) {
scanner.close();
}
public class Column {
private List<Integer> values;
private final String name;
public Column(String name) {
this.name = name;
this.values = new ArrayList<>();
}
public List<Integer> getValues() {
return values;
}
public void addValue(int value) {
this.values.add(Integer.valueOf(value));
}
public String getName() {
return name;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(name);
builder.append(": ");
for (int i = 0; i < values.size(); i++) {
int value = values.get(i);
builder.append(value);
if (i < (values.size() - 1)) {
builder.append(", ");
}
}
return builder.toString();
}
}
}

Using LinkedHashMap to store header(as Keys). LinkedHashMap preserves the insertion-order:
public void readFile() {
Map<String, String> map = new LinkedHashMap<String, String>();
boolean setInitValues = true, setKeys = true;
String[] keys = null;
while (x.hasNext()) {
String a = x.nextLine();
String[] values = a.split(",");
if (setKeys) { // set keys
keys = Arrays.copyOfRange(values, 1, values.length);
setKeys = false;
} else {
if (setInitValues) { // set initial values
for (int i = 1; i < values.length; i++)
map.put(keys[i - 1], values[i].trim());
setInitValues = false;
} else
// continue appending values
for (int i = 1; i < values.length; i++)
map.put(keys[i - 1],
map.get(keys[i - 1]).concat(values[i].trim()));
}
}
printMap(map); // print what you got
}
void printMap(Map<String, String> map) {
for (Map.Entry<String, String> entry : map.entrySet())
System.out.println("Key : " + entry.getKey() + " Value : "
+ entry.getValue());
}
Output :
Key : A Value : 1876
Key : B Value : 2187
Key : C Value : 3218
Key : D Value : 4321
Key : E Value : 5432
Key : F Value : 6543
Key : G Value : 7654
Key : H Value : 8765

Related

How to split string provided as user enter in java?

How to split a type of car and color that user provides as input.
Input format is:
<Type>#<Color>
Output will show how many type of car that has the same color
input example:
how many cars : 10
sedan#red
truck#yellow
van#white
suv#black
sedan#black
roadster#red
suv#gray
coupe#gray
minivan#white
truck#red
output has to be sort in alphabetical
black 2
gray 2
red 3
white 2
yellow 1
Tried a sample code, still not done, but where kinda struggle about how to split the array T^T
Class1:
public class Class1 {
private String type ;
private String color;
private String format;
public Class1() {
this.type = "";
this.color = "";
this.format = "";
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public void split () {
String part[] = format.split("#");
setType(part[0]);
setColor(part[1]); // i don't know if this will work or not..
}
}
Class2:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Class2 {
public static void main(String[] args) throws NumberFormatException, IOException {
// TODO Auto-generated method stub
int n ;
String format ;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
Class1 [] dataArray = new Class1[n] ;
Class1 data = new Class1();
for(int a = 0 ; a <= dataArray.length ; a++) {
dataArray[a] = data;
data.setFormat(br.readLine());
data.split();
data.getType();
data.getColor();
}
}
}
Coding is still not completed and still don't know how to split the array. Please help me solve this!
Change your for loop from this:
for(int a = 0 ; a <= dataArray.length ; a++) {
dataArray[a] = data;
data.setFormat(br.readLine());
data.split();
data.getType();
data.getColor();
}
to this:
for(int a = 0 ; a < dataArray.length ; a++) {
Class1 data = new Class1();
dataArray[a] = data;
data.setFormat(br.readLine());
data.split();
data.getType();
data.getColor();
}
The two important changes are:
You should only loop while a < dataArray.length, otherwise
you'll get an ArrayIndexOutOfBoundsException when a == dataArray.length.
You need to create a new instance of Class1 each time you read in
a new line, and store in position a of your dataArray
Other than this it looks fine. Obviously there are some quibbles in your design - maybe setFormat should call split, rather than requiring a separate call? - but you should now be able to iterate over dataArray and count colours, probably using a Map<String, Integer>
Initialize the new object Class1 data = new Class1(); inside the for-loop, rather than outside of it as otherwise it will be overridden every time the loop runs.
Also iterate through a < dataArray.length instead of a <= dataArray.length.
I have added the groupingBy to get the count grouped by the the color name. Then I sorted the entrySet of the resulting Map<String, Integer> and printed out the contents.
I have achieved the expected output without modifying your code too much.
public static void main(String[] args){
try{
int numberOfCars;
String format ;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
numberOfCars = Integer.parseInt(br.readLine());
Class1 [] dataArray = new Class1[numberOfCars] ;
for(int a = 0 ; a < dataArray.length ; a++) {
//Initializing new instance everytime
Class1 data = new Class1();
data.setFormat(br.readLine());
data.split();
dataArray[a] = data;
}
//Creating a Stream of Class1 objects
Arrays.stream(dataArray)
.collect(Collectors.groupingBy(car -> car.getColor(), Collectors.counting()))
.entrySet() //Getting entries from Map
.stream() //sorting after the Map is created to preserve the sorted order
.sorted(Comparator.comparing(entry -> entry.getKey())) //Sorting by key, that is the Color property of Class1
.forEach((entry) -> System.out.println(entry.getKey() + " "+ entry.getValue()));
}catch (NumberFormatException | IOException | ArrayIndexOutOfBoundsException e) {
System.out.println("Error occurred try again");
e.printStackTrace();
}
}

how to get particular element from ArrayList

Hello I am solving this problem given to me where I have to find average salary of a person which has least index id
import java.util.*;
import java.io.*;
public class Main {
public static int processData(ArrayList<String> array) {
for (String elem :array){
System.out.println(elem);
}
return 0;
}
public static void main (String[] args) {
ArrayList<String> inputData = new ArrayList<String>();
try {
Scanner in = new Scanner(new BufferedReader(new FileReader("input.txt")));
while(in.hasNextLine()) {
String line = in.nextLine().trim();
if (!line.isEmpty()) // Ignore blank lines
inputData.add(line);
}
int retVal = processData(inputData);
PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter("output.txt")));
output.println("" + retVal);
output.close();
} catch (IOException e) {
System.out.println("IO error in input.txt or output.txt");
}
}
}
the program is accepting input from text file as follows
282, ij, 11, 1600000
273, cbg, 12, 800000
567, nj, 11, 800000
539, cb, 11, 600000
So the output will be
11 520000
I am able to print the elements from array list but not been able to access particular elements. Can anyone help me to access particular element which is, in this case, 11,160000 and so on?
Thank you in advance
Hint
You can calculate the AVG of the index 11 like this :
public static int processData(ArrayList<String> array) {
String[] spl;
int avg = 0, nbr = 0;
for (String elem : array) {
//split your String with ", " and space
spl = elem.split(", ");
//the index exist in the 3ed position, so you have to check your index if 11 then you can get its value
if(spl[2].equals("11")){
avg+=Integer.parseInt(spl[3]);
nbr++;
}
System.out.println(elem);
}
System.out.println((avg/nbr));
return avg / nbr;
}
When you print in your code you have to use :
output.println("11 " + retVal);
Hope this can gives you an idea.
You create a List of String to store employee data that contains multiple fields.
You should not as it mixes data employees.
The general idea I propose you :
1) Instead of storing all information in a List of String, use a List of Employee.
replace
ArrayList<String> inputData = new ArrayList<String>();
by
List<Employee> employees = new ArrayList<Employee>();
2)Use each read line that represents a person to create a instance of a custom Object, for example Employee.
So replace
inputData.add(line);
by something like that
String[] token = line.split(",");
Employee employee= new Employee(Integer.valueOf(token[0]),token[1],Integer.valueOf(token[2]),Integer.valueOftoken[3]));
employees.add(employee);
3) During this iteration to read the file, you can store in a variable that is the Employee with the minimum id.
4) After reading the file, you know the Employee with the minimum id. So you can iterate on the List of Employee and sum the salaries of the Employee that has this id and count the number of salary for this Employee.
When the loop is finished compute the avg : float avg = sum / (float)count;
It is not the most optimized way but it makes the job.
The following code will do what you need.
public class MyMain {
private static String inputFilePath = "/path/to/input.txt";
private static String outputFilePath = "/path/to/output.txt";
public static int processData(ArrayList<MyData> array) {
if (array.size() > 0) {
int minId = array.get(0).getData3();
for (MyData elem : array) {
if(elem.getData3() < minId) {
minId = elem.getData3();
}
}
int count = 0;
int total = 0;
for (MyData myData : array) {
if(myData.getData3() == minId) {
count++;
total += myData.getData4();
}
}
System.out.println("Min ID : " + minId + " -- Avg Sal : " + total/count);
}
return 0;
}
public static void main(String[] args) {
ArrayList<MyData> inputData = new ArrayList<>();
try {
Scanner in = new Scanner(new BufferedReader(new FileReader(inputFilePath)));
while (in.hasNextLine()) {
String line = in.nextLine().trim();
if (!line.isEmpty()) // Ignore blank lines
inputData.add(new MyData(line));
}
int retVal = processData(inputData);
PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(outputFilePath)));
output.println("" + retVal);
output.close();
} catch (IOException e) {
System.out.println("IO error in input.txt or output.txt");
}
}
}
class MyData {
int data1;
String data2;
int data3;
int data4;
public MyData() {
// TODO Auto-generated constructor stub
}
public MyData(String data) {
String dataArr[] = data.split(",");
this.data1 = Integer.parseInt(dataArr[0].trim());
this.data2 = dataArr[1].trim();
this.data3 = Integer.parseInt(dataArr[2].trim());
this.data4 = Integer.parseInt(dataArr[3].trim());
}
public int getData1() {
return data1;
}
public void setData1(int data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public int getData3() {
return data3;
}
public void setData3(int data3) {
this.data3 = data3;
}
public int getData4() {
return data4;
}
public void setData4(int data4) {
this.data4 = data4;
}
}

How to convert ArrayList instanceObject to toString

i want to convert the instance of class which is in ArrayList to toString i have here my code
User class:
public class User {
// ...
public void setName(String name) {
this.fullname = name;
}
#Override
public String toString() {
return this.fullname;
}
public ArrayList<User> getTheLikers() {
ArrayList<User> user = new ArrayList<>();
user.add(this);
return user;
}
Post class:
public class Post {
public ArrayList<User> getLikers() {
User a = new User();
ArrayList<User> b = a.getTheLikers();
return b;
}
and here is the code where i should get the getLikers()
while(rs.next()) {
User a = new User();
Post b = new Post();
String name = rs.getString("people_who_like");
a.setName(name);
ArrayList c;
c = b.getLikers();
String liker = c.toString();
p.addElement(liker);
}
i have already convert it to toString as you can see.. but it shows that i have display my value but it is in null
To convert ArrayList into a String. That is specifically what the question says.
ArrayList c;
c = b.getLikers();
String liker = "";
for (String s : c){
liker += s + "\t";
}
When using Java 8 you can use String#join for this:
String liker = String.join(", ", c);
or the Stream API:
String liker = c.stream().collect(Collectors.joining(", "));
Pre Java 8 you have use e.g. Guava for this or write our own function
public static String listToString(final List<String> list) {
final StringBuilder result = new StringBuilder();
for (int i = 0; i < list.size() - 1; i++) {
result.append(list.get(i));
result.append(", ");
}
result.append(list.get(list.size() - 1));
return result.toString();
}
Even the list having the method List.toString() where u can get list into the String format.
how ever here the one thing that u can use your list to convert into the string.
Use the static variable for the list.
public class MainClass {
static ArrayList<String> arrayList = new ArrayList<String>();
public static void main(String args[]) {
arrayList.add("Krish");
arrayList.add("Krish1");
arrayList.add("Krish2");
arrayList.add("Krish3");
arrayList.add("Krish4");
System.out.println(arrayList.toString());
}
}
Similar u can use tostring method like this. if u using just arraylist then it will give out put in string format.
other way to do this.
public static String arrayliststring(ArrayList arrayList) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < arrayList.size(); i++) {
buffer.append(arrayList.get(i).toString() + " ");
}
return buffer.toString();
}
hope this helps and for java 8 as ifloop said that is correct.

find most occurrences in a string Java

My program is working fine on all parts except one. I am attempting to post as little code as possible. Please let me know if more is needed.
How do I find the name that occurs the most in a String, or StringBuilder? The "getWinner" method is where I am having trouble. I want to find the name (or winner) that occurs the most in a string. If their is a tie, the name that appears first is sufficient. Thanks in advance!
import java.util.ArrayList;
public class BallotBox
{
private ArrayList<String> ballots;
public BallotBox()
{
ballots = new ArrayList<String>();
}
public void addVote(String candidate)
{
ballots.add(candidate);
}
//****below is the method that's presenting a problem.****
public String getWinner()
{
StringBuilder candidates = new StringBuilder();
String winner = "";
for(int i = 0; i < ballots.size(); i++)
{
}
return winner;
}
public int getVoteCount(String candidate)
{
int count = 0;
for(int i = 0; i < ballots.size(); i++)
{
if(ballots.get(i).equals(candidate))
{
count++;
}
}
return count;
}
public String getResults()
{
StringBuilder resultTable = new StringBuilder();
ArrayList<String> printed = new ArrayList<String>();
for (String candidate : ballots)
{
if (!printed.contains(candidate))
{
resultTable.append(String.format("%s (%d)\n", candidate, getVoteCount(candidate)));
printed.add(candidate);
}
}
return resultTable.toString();
}
}
You can try to convert the list to a Set and use the Collections.frequency method.
Set<String> uniqueSet = new HashSet<String>(list);
for (String temp : uniqueSet)
{
System.out.println(temp + ": " + Collections.frequency(list, temp));
}
You'll get the output as shown below.
d: 1
b: 2
c: 2
a: 4
Check the link for more details
http://www.mkyong.com/java/how-to-count-duplicated-items-in-java-list/
You can use a HashMap to keep the votes for every candidate, and update the winner as soon as you find a new winner (more votes than the current winner):
public String getWinner()
{
final Map<String, Integer> votesCount = new HashMap<String, Integer>();
String winner = ballots.get(0);
int winnerVotes = 1;
for(final String ballot : ballots)
{
if (!votesCount.containsKey(ballot))
votesCount.put(ballot, 0);
votesCount.put(ballot, votesCount.get(ballot)+1);
if (votesCount.get(ballot)>winnerVotes)
{
winner = ballot;
winnerVotes = votesCount.get(ballot);
}
}
return winner;
}
Here is a working example. Hope this explains how the above code can be used in your application.
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class BallotBox
{
private ArrayList<String> ballots;
public BallotBox()
{
ballots = new ArrayList<String>();
ballots.add("John");
ballots.add("Eric");
ballots.add("Mary");
ballots.add("Eric");
ballots.add("Mary");
ballots.add("Mary");
ballots.add("John");
ballots.add("Mary");
}
public void addVote(String candidate)
{
ballots.add(candidate);
}
// ****below is the method that's presenting a problem.****
public String getWinner()
{
String winner = "";
// To check who has the highest votes.
int highestVotes = 0;
Set<String> uniqueSet = new HashSet<String>(ballots);
for (String temp : uniqueSet)
{
// The count of each Candidate's votes.
int count = Collections.frequency(ballots, temp);
// The winner is the one with the highest votes.
if(count > highestVotes)
{
highestVotes = count;
winner = temp;
}
}
return winner;
}
public static void main(String[] args)
{
BallotBox ballotBox = new BallotBox();
System.out.println(ballotBox.getWinner());
}
}

ArrayList sort for String, int [duplicate]

This question already has answers here:
Sort ArrayList of custom Objects by property
(29 answers)
How to sort Arraylist of objects
(3 answers)
Closed 9 years ago.
I m looking to sort an ArrayList which is of the type <String,int>, according to int.
So, my variable is var<String,int>
India 2
Pakistan 3
USA 1
The output becomes:
USA 1
India 2
Pakistan 3
I am confused how does it works with int. Collections.sort(var) does not works with it.
You can't use ArrayList of type
<String, int>
You can't have primitives in ArrayList as ArrayList holds objects. So, the closest you can do is to store Integer objects.
ArrayList can be of only one type if you are parameterizing it.
If you want to hold String and int, you can create a class CountryInfo with fields name and rank. Then create
ArrayList<CountryInfo> list =new ArrayList<CountryInfo>();
Then you can use
Collections.sort(list, <Comparator>)
I have created an example where you can sort your ArrayList even if its with objects. You can read through it an see if it's helps.
I have made two classes and a test class:
First class is Country:
public class Country {
private String countryName;
private int number;
public Country(String countryName, int number){
this.countryName = countryName;
this.number = number;
}
public String getCountryName(){
return countryName;
}
public void setCountryName(String newCountryName){
countryName = newCountryName;
}
public int getNumber(){
return number;
}
public void setNumber(int newNumber){
number = newNumber;
}
public String toString(){
return getCountryName() + getNumber();
}
}
Next class is Methods:
public class Methods {
private Country country;
private ArrayList<Country> overview = new ArrayList<Country>();
private ArrayList<Country> overviewSorted = new ArrayList<Country>();
int [] test;
public void regCountry(String countryname, int numbers){
if(!(countryname == "" && numbers == 0)){
overview.add(new Country(countryname, numbers));
} else {
System.out.println("The input was null");
}
}
public void showRegisteredCountries(){
if(!(overview.size() < 0)){
for(int i = 0; i < overview.size(); i++){
System.out.println("The country: " + overview.get(i).getCountryName() + " has the number: " + overview.get(i).getNumber() + " registered");
}
} else {
System.out.println("There are no country registered");
}
}
public void numbersOverFromArrayList(){
if(!(overview.size() < 0)){
test = new int [overview.size()];
for(int i = 0; i < overview.size(); i++){
test[i] = overview.get(i).getNumber();
}
}
}
public void sortArrayAndCopyItBack(){
if(!(test.length < 0)){
java.util.Arrays.sort(test);
for(int i = 0; i < test.length; i ++){
for(int j = 0; j < overview.size(); j++){
if(test[i] == overview.get(j).getNumber()){
overviewSorted.add(new Country(overview.get(j).getCountryName(), overview.get(j).getNumber()));
}
}
}
}
}
public void showTableSorted(){
if(!(overviewSorted.size() < 0)){
for(int i = 0; i < overviewSorted.size(); i++){
System.out.println("Country name: " + overviewSorted.get(i).getCountryName() + " with number: " + overviewSorted.get(i).getNumber());
}
} else {
System.out.println("There are non countrys in table that is sorted");
}
}
}
Next is the test class:
public class test2 {
public static void main(String [] args){
Methods methodes = new Methods();
for(int i = 0; i < 4; i++){
String inCountry = JOptionPane.showInputDialog("Country:");
String inNumber = JOptionPane.showInputDialog("number:");
String country = inCountry;
int number = Integer.parseInt(inNumber);
methodes.regCountry(country, number);
}
methodes.showRegisteredCountries();
methodes.numbersOverFromArrayList();
methodes.sortArrayAndCopyItBack();
methodes.showTableSorted();
}
}
My output:
The country: Norway has the number: 5 registered
The country: Sweden has the number: 2 registered
The country: Denmark has the number: 9 registered
The country: Finland has the number: 7 registered
Country name: Sweden with number: 2
Country name: Norway with number: 5
Country name: Finland with number: 7
Country name: Denmark with number: 9
That is not an ArrayList. Use TreeMap in Stead.
Map<String, Integer> countryInfo = new TreeMap<String,Integer>();
This way it will be sorted automatically
You can sort
use Collections.sort(list,Comparator implementation)
in the implementation(here I have used anonymous implementation) override compare method
where you
get last character of each string convert to string and compare them
ArrayList<String> a=new ArrayList<String>();
a.add("India 2");
a.add("Pakistan 3");
a.add("USA 1");
Collections.sort(a, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
Integer i=Integer.valueOf(o1.substring((o1.length() -1),o1.length()));
Integer j=Integer.valueOf(o2.substring((o2.length() -1),o2.length()));
return i.compareTo(j);
}
});
You can optimist code
ArrayList is a collection of one type of object. It is not like maps that can take two inputs.
Therefore, there are three options:
1. Make use of a TreeMap that contains both a Key and a Map and is automatically sorted by key or
2. Make use of an unsorted map and sort with a comparator - see Sort a Map<Key, Value> by values (Java) or
3. Use an arraylist of a custom class with a comparator.
-
1) Using a TreeMap
Treemaps are an implementation of red-black trees. See: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/TreeMap.html
TreeMap<Integer,String> countries = new TreeMap<Integer,String>();
countries.put(2, "India");
countries.put(1, "USA");
countries.put(3, "Pakistan");
Iterator<Entry<Integer, String>> it = countries.entrySet().iterator();
Entry<Integer, String> entry;
while(it.hasNext())
{
entry = it.next();
System.out.println(entry.getValue() + " " + entry.getKey());
}
And this Produces:
USA 1
India 2
Pakistan 3
-
2) Make use of an unsorted map and sort with a comparator
See: Sort a Map<Key, Value> by values (Java) as the answer is very will written.
-
3) Using an ArrayList with Country Class
In order to support your example you would need to create a Country class.
You would need to do the following:
Implement Comparable within your country class and place the logic for the comparison within there.
Create a custom comparator that you will give to your Collection.sort invocation.
import java.util.ArrayList;
import java.util.Collections;
import java.util.InputMismatchException;
import java.util.Iterator;
public class CountrySortExample {
public static void main(String[] args) {
new CountrySortExample();
}
public ArrayList<Country> countries = new ArrayList<Country>();
public CountrySortExample()
{
countries.add(new Country("India",2));
countries.add(new Country("Pakistan",3));
countries.add(new Country("USA",1));
Collections.sort(countries);
Iterator<Country> it = countries.iterator();
Country count;
while(it.hasNext())
{
count = it.next();
System.out.println(count.CountryName + " " + count.CountryIndex);
}
}
class Country implements Comparable
{
public String CountryName;
public int CountryIndex;
public Country(String CountryName,int CountryIndex )
{
this.CountryName = CountryName;
this.CountryIndex = CountryIndex;
}
#Override
public int compareTo(Object o) {
if(! (o instanceof Country))
throw new InputMismatchException("Country is expected");
Country other = (Country)o;
if(other.CountryIndex > CountryIndex)
return -1;
else if(other.CountryIndex == CountryIndex)
return 0;
else return 1;
}
}
}
Further information is available at: http://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/
If you have an object that you want to sort in more than one way, you define a Comparator class for each type of sort you want to do.
Using the example that the OP gave, here's one way to define the object and Comparators.
Here's one test result:
CountryRating [name=India, rating=2]
CountryRating [name=Pakistan, rating=3]
CountryRating [name=USA, rating=1]
CountryRating [name=USA, rating=1]
CountryRating [name=India, rating=2]
CountryRating [name=Pakistan, rating=3]
And here's the example code:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CountryRating {
private String name;
private int rating;
public CountryRating(String name, int rating) {
this.name = name;
this.rating = rating;
}
public String getName() {
return name;
}
public int getRating() {
return rating;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CountryRating [name=");
builder.append(name);
builder.append(", rating=");
builder.append(rating);
builder.append("]");
return builder.toString();
}
public static void main(String[] args) {
List<CountryRating> list = new ArrayList<CountryRating>();
CountryRating cr1 = new CountryRating("USA", 1);
CountryRating cr2 = new CountryRating("India", 2);
CountryRating cr3 = new CountryRating("Pakistan", 3);
list.add(cr1);
list.add(cr2);
list.add(cr3);
Collections.sort(list, new CountrySort());
printList(list);
System.out.println(" ");
Collections.sort(list, new RatingSort());
printList(list);
}
private static void printList(List<CountryRating> list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
class CountrySort implements Comparator<CountryRating> {
#Override
public int compare(CountryRating cr1, CountryRating cr2) {
return cr1.getName().compareTo(cr2.getName());
}
}
class RatingSort implements Comparator<CountryRating> {
#Override
public int compare(CountryRating cr1, CountryRating cr2) {
return cr1.getRating() - cr2.getRating();
}
}

Categories