Sort a vector of custom objects - java

How can I sort a vector of my custom object and choose which property to sort by?
I did see this question & answer but I'm not too sure what its sorting it based on. Code example would be prefered to "methodology".
Sort a Vector of custom objects
public class ItemLocation {
String icon;
String title;
String message;
String subtext;
String deviceId;
double latCoords;
double lngCoords;
int expiary;
int id;
double proximity;
String locSeen;
}

Below is a example that will allow you to sort by a specified field of ItemLocation:
public void sort(final String field, List<ItemLocation> itemLocationList) {
Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
#Override
public int compare(ItemLocation o1, ItemLocation o2) {
if(field.equals("icon")) {
return o1.icon.compareTo(o2.icon);
} if(field.equals("title")) {
return o1.title.compareTo(o2.title);
} else if(field.equals("message")) {
return o1.message.compareTo(o2.message);
}
.
. fill in the rest of the fields...
.
else if(field.equals("locSeen")) {
return o1.locSeen.compareTo(o2.locSeen);
}
}
});
}

See the JavaDocs for java.util.Comparable and java.util.Comparator.
A class that implements Comparable can be compared against other instances of that class. This is useful to implement a natural search order. To allow ordering other than the class's natural order you would need to implement a Comparator. A Comparator is a separate object that is capable of comparing two other objects using whatever criteria it wants.
In your case you'd probably want to implement a Comparator for each of the different properties that you want to order by, or one that can be configured.
Comparable and Comparator both use the same idea to determine ordering: A method returns less than 0, 0, or greater than 0 to inform the caller which of the 2 objects is ordered first. In the case of Comparable the first object is this.

This one works:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* ComparableDemo
* #author Michael
* #since 2/24/11
*/
public class ComparableDemo
{
public static void main(String[] args)
{
List<ItemLocation> itemLocations = new ArrayList<ItemLocation>();
for (String arg : args)
{
itemLocations.add(new ItemLocation(arg));
}
System.out.println("before sort: " + itemLocations);
Comparator<ItemLocation> comparator = new ItemLocationComparator();
Collections.sort(itemLocations, comparator);
System.out.println("after sort: " + itemLocations);
}
}
class ItemLocation
{
String icon;
String title;
String message;
String subtext;
String deviceId;
double latCoords;
double lngCoords;
int expiary;
int id;
double proximity;
String locSeen;
ItemLocation(String message)
{
this("", "", message, "", "", 0.0, 0.0, 0, 0, 0.0, "");
}
ItemLocation(String icon, String title, String message, String subtext, String deviceId, double latCoords, double lngCoords, int expiary, int id, double proximity, String locSeen)
{
this.icon = icon;
this.title = title;
this.message = message;
this.subtext = subtext;
this.deviceId = deviceId;
this.latCoords = latCoords;
this.lngCoords = lngCoords;
this.expiary = expiary;
this.id = id;
this.proximity = proximity;
this.locSeen = locSeen;
}
#Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append("ItemLocation");
sb.append("{message='").append(message).append('\'');
sb.append('}');
return sb.toString();
}
}
class ItemLocationComparator implements Comparator<ItemLocation>
{
public int compare(ItemLocation o1, ItemLocation o2)
{
return o1.message.compareTo(o2.message);
}
}
Here's the output:
C:\JDKs\jdk1.6.0_21\bin\java -Didea.launcher.port=7534 "-Didea.launcher.bin.path=C:\Program Files\JetBrains\IntelliJ IDEA 10.0.2\bin" -Dfile.encoding=windows-1252 com.intellij.rt.execution.application.AppMain ComparableDemo zeb meme apple
before sort: [ItemLocation{message='zeb'}, ItemLocation{message='meme'}, ItemLocation{message='apple'}]
after sort: [ItemLocation{message='apple'}, ItemLocation{message='meme'}, ItemLocation{message='zeb'}]
Process finished with exit code 0

Let's say we have a class with an int and a string. I can define how one object of that class may be compared against other.
I could choose any criteria. For instance, I may decide to sort based on the int. If I happen to have two int's with the same value, I may decide the string as an additional criteria, something like this:
// this class *knows* how to "compare" against him self
class CustomObject implements Comparable<CustomObject> {
String aString;
int aInt;
...
public int compareTo(CustomObject two ) {
int diff = this.aInt - two.aInt;//<-- compare ints
if( diff != 0 ) { // they have different int
return diff;
}
return this.aString.compareTo( two.aString );//<-- compare strings...
}
...
}
Here's a complete running demo ...
import java.util.*;
class SortDemo {
public static void main( String ... args ) {
// create a bunch and sort them
List<CustomObject> list = Arrays.asList(
new CustomObject(3, "Blah"),
new CustomObject(30, "Bar"),
new CustomObject(1, "Zzz"),
new CustomObject(1, "Aaa")
);
System.out.println( "before: "+ list );
Collections.sort( list );
System.out.println( "after : "+ list );
}
}
// this class *knows* how to "compare" against him self
class CustomObject implements Comparable<CustomObject> {
String aString;
int aInt;
CustomObject( int i, String s ) {
aInt = i;
aString = s;
}
// comparable interface lets you
// specify "HOW" to compare two
// custom objects
public int compareTo(CustomObject two ) {
// I migth compare them using the int first
// and if they're the same, use the string...
int diff = this.aInt - two.aInt;
if( diff != 0 ) { // they have different int
return diff;
}
// else let the strings compare them selves
return this.aString.compareTo( two.aString );
}
public String toString(){
return "CustomObject[aInt="+aInt+", aString="+aString+"]";
}
}
Here's the output:
before: [CustomObject[aInt=3, aString=Blah], CustomObject[aInt=30, aString=Bar], CustomObject[aInt=1, aString=Zzz], CustomObject[aInt=1, aString=Aaa]]
after : [CustomObject[aInt=1, aString=Aaa], CustomObject[aInt=1, aString=Zzz], CustomObject[aInt=3, aString=Blah], CustomObject[aInt=30, aString=Bar]]
I hope that's clear enough
You can also pass a custom comparator. Let me know if you need a sample of that.

Related

Why is my TreeSet in Java giving me a null pointer exception when I try to add a String? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 11 months ago.
I'm working on a project for a Java class, and I can't seem to get past this NullPointerException. The project is a command-line LinkedIn program. One of the aspects I'm implementing is the ability to add a skillset to a user's profile.
I have a LinkedInUser class in which I define a TreeSet to hold these skillsets in the form of Strings entered by the user. I'm using TreeSet, because the assignment requires them to be sorted.
I define the TreeSet in the LinkedInUser class here:
private Set<String> skillsets = new TreeSet<>();
The action the user takes is defined in the AddSkillsetAction class:
String skillset;
System.out.println("Enter a skillset to add to your list:");
skillset = scanner.nextLine();
loggedInUser.addSkillset(skillset);
System.out.println(skillset + " has been added to your skillsets.");
And the String they enter is passed to the addSkillSet function in the LinkedInUser class:
public void addSkillset(String skillset) {
skillsets.add(skillset);
}
I keep getting a NullPointerException on the line:
skillsets.add(skillset);
What am I doing wrong? I've tested every level up to that line. I even tested the TreeSet inside the addSkillset function with this code:
if(skillsets == null) {
System.out.println("The TreeSet is null.")
}
It's telling me the TreeSet is null. I thought instantiating the Set with:
private Set<String> skillsets = new TreeSet<>();
would actually create an empty TreeSet, instead of it pointing to a null location. Why is my set "skillsets" still pointing to null? What am I doing wrong here?
EDIT:
Here are the full classes:
package edu.institution.asn2;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class LinkedInUser extends UserAccount implements Comparable<LinkedInUser>, Serializable {
private static final long serialVersionUID = 75648957489235739L;
private String type;
private List<LinkedInUser> connections = new ArrayList<>();
private Set<String> skillsets = new TreeSet<>();
public LinkedInUser(String username, String password) {
super(username, password);
}
#Override
public void setType(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
// Add a connection to user's list
public void addConnection(LinkedInUser user) throws LinkedInException {
int index = connections.indexOf(user);
if (index >= 0) {
throw new LinkedInException("You are already connected with this user.");
}
else {
connections.add(user);
}
}
// Remove a connection from the user's connection list
public void removeConnection(LinkedInUser user) throws LinkedInException {
int index = connections.indexOf(user);
if (index < 0) {
throw new LinkedInException("You are NOT connected to this user.");
}
else {
connections.remove(index);
}
}
// Return a copy of the ArrayList of connections
public List<LinkedInUser> getConnections() {
ArrayList<LinkedInUser> copy = new ArrayList<>(connections);
return copy;
}
// Return the number of connections
public int getNumberOfConnections() {
return connections.size();
}
// Return the skillsets
public Set<String> getSkillsets(){
return skillsets;
}
// Add a skillset
public void addSkillset(String skillset) {
skillsets.add(skillset);
}
// Remove a skillset
public void removeSkillset (String skillset) {
if(skillsets.contains(skillset)){
skillsets.remove(skillset);
} else {
System.out.println(skillset + " is not in your skills list.");
}
}
// Override the compareTo function
#Override
public int compareTo(LinkedInUser user) {
int i = this.getUsername().compareToIgnoreCase(user.getUsername());
return i;
}
}
And the class to add a skillset:
package edu.institution.actions.asn7;
import java.util.Scanner;
import edu.institution.ApplicationHelper;
import edu.institution.UserRepository;
import edu.institution.actions.MenuAction;
import edu.institution.asn2.LinkedInUser;
public class AddSkillsetAction implements MenuAction {
#Override
public boolean process(Scanner scanner, UserRepository userRepository, LinkedInUser loggedInUser) {
String skillset;
System.out.println("Enter a skillset to add to your list:");
skillset = scanner.nextLine();
loggedInUser.addSkillset(skillset);
System.out.println(skillset + " has been added to your skillsets.");
ApplicationHelper.incrementSkillsetCount(skillset);
return true;
}
}
After I run and try to add a skillset, I get this error:
Exception in thread "main" java.lang.NullPointerException
at edu.institution.asn2.LinkedInUser.addSkillset(LinkedInUser.java:69)
at edu.institution.actions.asn7.AddSkillsetAction.process(AddSkillsetAction.java:19)
at edu.institution.ApplicationController.process(ApplicationController.java:61)
at edu.institution.LinkedInCLI.main(LinkedInCLI.java:39)
LinkedInUser.java:69 is:
skillsets.add(skillset);
By the way… Your naming is confusing. String skillset; should be String skill, and .addSkill not .addSkillset, because you are adding individual skills rather than adding a set.
Clarifying your naming may clarify your code. Notice the singular skill and plural skills naming used in code below.
You did not provide enough details to diagnose the problem. But I can show you some example code based on your descriptions.
Your problem may be related to your not properly instantiating the TreeSet. Notice in this code that you have a choice of at least two places in which to instantiate:
On the declaration line of skills.
In the constructor. (Code currently commented-out.)
The LinkedInUser class.
package work.basil.linkedin;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;
public class LinkedInUser
{
private String name;
private NavigableSet < String > skills = new TreeSet <>();
// Constructor
public LinkedInUser ( final String name )
{
this.name = name;
// this.skills = new TreeSet <>() ;
}
// Modifiers
public void setName ( String name ) { this.name = name; }
public void addSkill ( String skill ) { this.skills.add( skill ); }
// Getters
public String getName ( ) { return name; }
public Set < String > getSkills ( ) { return Set.copyOf( this.skills ); } // Return a unmodifiable copy of the set. (defensive programming)
}
For defensive programming, we return a copy of the set. This unmodifiable copy returned by Set.copyOf has no order. In some implementations, the order may even change arbitrarily for each iterator. If you want to return an ordered NavigableSet instead, do this:
Change the return type of the method to NavigableSet.
Change the code to pass the instance’s set to the constructor of another set.
public NavigableSet < String > getSkills ( ) { return new TreeSet <>(this.skills ); }
Usage.
LinkedInUser alice = new LinkedInUser( "Alice" );
LinkedInUser bob = new LinkedInUser( "Bob" );
alice.addSkill( "Yodeling" );
alice.addSkill( "Tap Dancing" );
bob.addSkill( "Juggling" );
System.out.println( alice.getName() + " does " + alice.getSkills() );
System.out.println( bob.getName() + " does " + bob.getSkills() );
System.out.println( List.of( alice , bob ) );
When run.
Alice does [Yodeling, Tap Dancing]
Bob does [Juggling]
[LinkedInUser{name='Alice', skills=[Tap Dancing, Yodeling]}, LinkedInUser{name='Bob', skills=[Juggling]}]
You said:
I thought instantiating the Set with:
private Set<String> skillsets = new TreeSet<>();
Yes, that would indeed instantiate a TreeSet object, and store a reference to that set in a variable named skillsets. I expect you are placing that code in the wrong location. Again, look at the two locations I suggested earlier in this Answer: on declaration line, or in constructor.

Multiple comparators in a class

I am hard stuck on a problem I cannot find a good answer to. I've found
this one about custom comparators, but it is incomplete:
class YourClass {
static Comparator<YourClass> getAttribute1Comparator() {
return new Comparator<YourClass>() {
// compare using attribute 1
};
}
static Comparator<YourClass> getAttribute2Comparator() {
return new Comparator<YourClass>() {
// compare using attribute 2
};
}
}
That should work, but I don't know how the comparison part works. Here is my class:
package ZVCVolkel_Logic;
import java.util.Comparator;
public class Vliegtuig implements Comparator<Vliegtuig>{
private String naam;
private String type;
private String status;
private Hangaar hangaar;
public Vliegtuig(String naam, String type, String status, Hangaar hangaar){
this.naam = naam;
this.type = type;
this.status = status;
this.hangaar = hangaar;
}
}
Now I need a comparator for status and for Hangaar.getName(). Can someone help?
It is not the one, he has only 1 comparator. I can get that working too but not with 2 different ones in 1 class.
The comparator interface has a method compare return an int value to determine the relation ship between two objects.
It will return:
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
static Comparator<Vliegtuig> hangaarNameComparator() {
return new Comparator<Vliegtuig>(){
public int compare(Vliegtuig one, Vliegtuig two) {
return one.getHangaar().getName().compareTo(two.getHangaar().getName());
}
}
}
Here you probably want to take care of NullPointerException if getHangaar() or hangaar.getName() return null.
In java 8 you could do this:
Comparator<Vliegtuig> hangaarNameComparator = Comparator.comparing(Vliegtuig::getHagaar,
Comparator.comparing(Hagaar::getName));
In the comparator implementation you need to compare 2 objects. You can refer to most of JDK classes for example, for instance java.lang.Integer.
In your case solution will be to use embedded compactors from objects like this:
Comparator<Vliegtuig> nameComparator = new Comparator<>() {
#Override
public int compare(Vliegtuig o1, Vliegtuig o2) {
return o1.getName().compareTo(o2.getName());
}
}
And you don't need to extend Comparator by the Vliegtuig.

How would I sort given this code [duplicate]

This question already has answers here:
How to use Comparator in Java to sort
(16 answers)
Closed 5 years ago.
I also have an ArrayList items. I have classes derived from Media. Given the code below, how would I sort the arraylist by duration? e.g.
Collections.sort(myMedia, ?);
Here is the class
import java.util.Comparator;
public abstract class Media implements Comparable<Media>{
private int duration;
private String title;
private String imageFileName;
private static String imageFileDirectory = "src/resources/";
public Media(String name, int seconds) {
this.title = name;
this.duration = seconds;
this.imageFileName = "";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getDuration() {
return duration;
}
public void setDuration(int d) {
this.duration = d;
}
public String getImageFileName() {
return imageFileName;
}
public void setImageFileName(String imageFileName) {
this.imageFileName = imageFileName;
}
public static String getImageFileDirectory() {
return imageFileDirectory;
}
public static void setImageFileDirectory(String imageFileDirectory) {
Media.imageFileDirectory = imageFileDirectory;
}
#Override
public String toString() {
return this.getTitle()
+ ", Duration: " + this.getDuration() + "s, " +
"Cost: " + costInPence() + "p";
}
public abstract int costInPence();
#Override
public int compareTo(Media o) {
return this.getTitle().compareTo(o.getTitle());
}
public static class DurationComparator implements Comparator<Media>{
public int compare(Media m1, Media m2) {
return m2.getDuration() - m1.getDuration();
}
}
public static class CostComparator implements Comparator<Media>{
public int compare(Media m1, Media m2) {
return m2.costInPence() - m1.costInPence();
}
}
}
The Collections#sort method has two variants.
The first variant (documentation) only accepts a collection that is to be sorted. It will sort the elements of the collection by their natural order. Therefore the elements must implement the interface Comparable which yields a compareTo method. Your Media objects already implement this interface with a meaningful natural order, namely sorting by their titles:
public abstract class Media implements Comparable<Media> {
#Override
public int compareTo(Media o) {
return this.getTitle().compareTo(o.getTitle());
}
}
The other variant (documentation) accepts a collection and a Comparator object. It will then sort the elements based on the order defined by the Comparator. You can define Comparator on various ways, since Java 8 it became pretty compact. But first let us take a look at the Comparator you have already defined, it sorts by duration:
public static class DurationComparator implements Comparator<Media> {
public int compare(Media m1, Media m2) {
return m2.getDuration() - m1.getDuration();
}
}
So if you want to sort by titles you should use the first variant. If you want to sort by duration you need to create a new instance of DurationComparator and use the second variant, alternatively use the compact Java 8 statements. The same holds for your CostComparator:
// Sort by title
Collections.sort(myMedia);
// Sort by duration
Collections.sort(myMedia, new DurationComparator<>());
// Sort by duration with Java 8
Collections.sort(myMedia, Comparator.comparingInt(Media::getDuration));
// Sort by cost
Collections.sort(myMedia, new CostComparator<>());
// Sort by cost with Java 8
Collections.sort(myMedia, Comparator.comparingInt(Media::costInPence));
The Comparator#comparing (documentation) method creates a Comparator object that sorts the given elements based on the given keys. The method reference points to a method that yields the keys.
As the methods return int you may choose the method Comparator#comparing (documentation) instead, it is slightly faster since int doesn't need to be boxed into Integer then.
Note that since Java 8 Lists itself provide a sort method too (documentation). So you don't need to call Collections anymore:
myMedia.sort(Comparator.comparingInt(Media::getDuration));
Also note that Comparator now provides some useful methods (documentation), for example to first sort by one key and if keys are equal then sort by a second key:
myMedia.sort(Comparator.comparingInt(Media::getDuration)
.thenComparing(Media::costInPence));

Sorting a Set of selfmade objects to an ArrayList (Java)

So I have to sort a Set (preferably a TreeSet) of items from the class "Article":
public abstract class Article {
String title;
String articleNumber;
public Article(String title, String articleNumber) {
this.title = title;
this.articleNumber = articleNumber;
}
public String getArticleNumber() {
return this.articleNumber;
}
}
public class Book extends Article {
String author;
public Book(String author, String title, String articleNumber) {
super(title, articleNumber);
this.author = author;
}
}
public class Song extends Article {
String interpret;
public Song(String interpret, String title, String articleNumber) {
super(title, articleNumber);
this.interpret = interpret;
}
}
Article is a nested class of OnlineShop which holds the original Set of Articles.
I've implemented the methods to add and remove articels, but I still need an method to sort the Articles of the set: Set<Article> availableArticles = new TreeSet<Article>();
according to the articleNumber value in an ArrayList.
I've tried this but it seems not to work: where unSorted is a List of Articles, but not the String values(how do i extract this?)
Collections.sort(unSorted, new Comparator<Article>() {
#Override
public int compare(Article a, Article b) {
return a.getArticleNumber().compareTo(b.getArticleNumber());
}
});
}
I think your atempt wasn't wrong. I assume that your article number is of the format "1234". Altough it is a String object, wich means, that if you want to sort it comparing its numbers, you have to parse the Strings to an int. Otherwise your comparator interprets your numbers as it's Byte based characters-which creates a mess-.
The untested solution, if my assumption is correct, looks like:
Collections.sort(unSorted, new Comparator<Article>() {
#Override
public int compare(Article a, Article b) {
return Integer.compare(Integer.parseInt(a.getArticleNumber()),Integer.parseInt(b.getArticleNumber()));
}
in my opinion it looks like a mess...better do this:
Collections.sort(unSorted, new Comparator<Article>() {
#Override
public int compare(Article a, Article b) {
int articleNumberOne = Integer.parseInt(a.getArticleNumber());
int articleNumberTwo = Integer.parseInt(b.getArticleNumber());
return Integer.compare(articleNumberOne, articleNumberTwo);
}
}
thanks to Holger for his advice :D
Thank you all for you input, ive achieved what i wanted with this method:
public ArrayList<Article> sortByArticleNumber() {
if (availableArticles.isEmpty()) {
System.out.println("No Articles available");
return new ArrayList<Article>();
}
ArrayList<Article> articles= new ArrayList<Article>(availableArticles);
// sort Methode wird überschrieben für ArrayList<Article> articles
Collections.sort(articles, new Comparator<Article>() {
#Override
public int compare(Article a, Article b) {
int a1 = Integer.parseInt(a.getArticleNumber());
int b1 = Integer.parseInt(b.getArticleNumber());
return Integer.compare(a1, b1);
}
});
System.out.println(articles.toString());
return articles;
}
public static void main(String args[]) {
try {
OnlineShop myShop = new OnlineShop();
//Set<Article> availableArticles = new TreeSet<Article>();
//availableArticles.add(myShop.new Article ("Dell", "1234567"){});
//availableArticles.add(myShop.new Article ("Alienware", "987654"){});
myShop.addArticle(myShop.new Article ("Dell", "9999"){});
myShop.addArticle(myShop.new Article ("Asio", "9888"){});
myShop.addArticle(myShop.new Article ("Alienware", "9001"){});
myShop.addArticle(myShop.new Song ("SSIO", "Bonn17", "5346"));
myShop.sortByArticleNumber();
}
catch (Throwable ex) {
System.err.println("Uncaught exception - " + ex.getMessage());
ex.printStackTrace(System.err);
}
}
The result is:
[Song [interpret=SSIO, title=Bonn17, articleNumber=5346]
, Article [title=Alienware, articleNumber=9001]
, Article [title=Asio, articleNumber=9888]
, Article [title=Dell, articleNumber=9999]
]

Java: Sorting text file lines

I'm using eclipse and I'm trying to sort a text file with about 40 lines that look like this:
1,Terminator,1984,Schwarzenegger
2,Avatar,2009,Worthington
3,Avengers,2012,Downey
4,Starwars,1977,Hammill
5,Alien,1979,Weaver
I want sort them alphabetically by the second field so that the text file is altered to look like this:
5,Alien,1979,Weaver
2,Avatar,2009,Worthington
3,Avengers,2012,Downey
4,Starwars,1977,Hammill
1,Terminator,1984,Schwarzenegger
I'm fairly certain I should be doing something involving tokenizing them (which I've already done to display it) and a BufferedWriter but I can't for the life of me think of a way to do it by the second or third field and I feel like I'm missing something obvious.
You will first of course need to read a file, which you can learn how to do here.
Java: How to read a text file
This example will provide several ways you may write the file once you have sorted your data.
How do I create a file and write to it in Java?
As for sorting, I recommend creating a class Movie, which would look similar to
public class Movie implements Comparable<Movie> {
private String name;
private String leadActor;
private Date releaseDate;
public Movie(String name, String leadActor, String releaseDate) {
}
#Override
public int compareTo(Movie other) {
}
}
Ill leave it to you fill in the rest of the constructor and compareTo method. Once you have your compareTo method you will be able to call Collections.sort(List list) passing your list of Movie.
Here are some resources on implementing Comparable.
http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
Why should a Java class implement comparable?
Your comparator
class SampleComparator implements Comparator<String> {
#Override
public int compare(String o1, String o2) {
String array1[] = o1.split(",");
String array2[] = o2.split(",");
return array1[1].compareTo(array2[1]);
}
}
Your Sorting
String [] lines= {"1,Terminator,1984,Schwarzenegger",
"2,Avatar,2009,Worthington",
"3,Avengers,2012,Downey",
"4,Starwars,1977,Hammill",
"5,Alien,1979,Weaver"};
List<String> rowList = new ArrayList<String>(Arrays.asList(lines));
Collections.sort(rowList, new SampleComparator());
for (String string : rowList) {
System.out.println(string);
}
Your Output
5,Alien,1979,Weaver
2,Avatar,2009,Worthington
3,Avengers,2012,Downey
4,Starwars,1977,Hammill
1,Terminator,1984,Schwarzenegger
If you have any doubt on this let me know..
The String class has a very helpful static method called "split". All you do is call split and put it in the delimiter and it gives back a String array with the split up string.
Here's an example:
String line = "How,Now,Brown,Cow";
String[] splitLine = line.split(",");
for(String l: splitLine)
{
System.out.println(l);
}
The above code would print the following:
How
Now
Brown
Cow
Hopefully you can use this and adapt it to your problem.
Good luck!
What you want to do is to use java.util.Comparator and Collections.sort. More on this can be found: http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
Following #Tyler answer. You can have a default implementation in the Movie class and additional sort orders that you can implement by calling Collections.sort(movieList, new MyComparator()); Here comes an example of both.
package com.stackoverflow;
public class Movie implements Comparable<Movie> {
private String name;
private String leadActor;
private String releaseDate;
public Movie(String name, String leadActor, String releaseDate) {
this.name = name;
this.leadActor = leadActor;
this.releaseDate = releaseDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLeadActor() {
return leadActor;
}
public void setLeadActor(String leadActor) {
this.leadActor = leadActor;
}
public String getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(String releaseDate) {
this.releaseDate = releaseDate;
}
#Override
public int compareTo(Movie other) {
return getName().compareTo(other.getName());
}
}
And if you want to make your own comparator called on your collection:
package com.stackoverflow;
import java.util.Comparator;
public class MyComparator implements Comparator<Movie> {
#Override
public int compare(Movie o1, Movie o2) {
return o1.getLeadActor().compareTo(o2.getLeadActor());
}
}
Try like this :--
ArrayList ar=new ArrayList();
String [] arr=new String[10];
int i=0;
try {
Scanner sc=new Scanner(file);
while (sc.hasNextLine())
{
String ss=sc.nextLine();
i=i+1;
arr[i]=ss;
}
ar.add(arr[5]);
ar.add(arr[2]);
ar.add(arr[3]);
ar.add(arr[4]);
ar.add(arr[1]);
System.out.println(ar);
}
This solution uses Java 8 APIs.
You don't really need to have an explicit implementation of Comparator or create a Comparable class. Using Comparator.comparing with lambda we can elegantly sort lines by custom key.
import java.io.IOException;
import java.nio.file.*;
import java.util.Comparator;
import java.util.stream.Stream;
public class FileSortWithStreams {
public static void main(String[] args) throws IOException {
Path initialFile = Paths.get("files/initial.txt");
Path sortedFile = Paths.get("files/sorted.txt");
int sortingKeyIndex = 1;
String separator = ",";
Stream<CharSequence> sortedLines =
Files.lines(initialFile)
.map(s -> s.split(separator))
.sorted(Comparator.comparing(s -> s[sortingKeyIndex]))
.map(s -> String.join(separator, s));
Files.write(sortedFile, sortedLines::iterator, StandardOpenOption.CREATE);
}
}

Categories