I want to order nodes' chosen string variables. this is an homework due to tomorrow.
public void sortSongName() {
DefaultSongs sortedList = new DefaultSongs();
int temp= Integer.MAX_VALUE;
Song curr=root;
Song hold = null;
while(root.nextSong != null) {
if(curr.getSongName().charAt(0)<hold.getSongName().charAt(0)) {
hold=curr;
curr=root.nextSong;
}else {
curr=root.nextSong;
}
sortedList.createSong(root.nextSong.getSongName(),root.nextSong.getBandName() , root.nextSong.getDuration());
deleteSong(root.nextSong.getSongName());
sortSongName();
}
}
Assuming your song class look something like this
public class Song {
private String name;
public String name() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
And the DefaultSongs class is just a repo with a list of Songs
public class DefaultSongs {
private final List<Song> songList;
public DefaultSongs() {
this.songList = new ArrayList<>();
}
public List<Song> songList() {
return songList;
}
}
Simplest way would be to use java stream
public void sortSongsByName(){
songList.stream().sorted(Comparator.comparing(Song::name));
}
The simplest way is to use Collections.sort();
For example:
List<String> songs = Arrays.asList("Bam","Cam", "Am","Dam");
Collections.sort(songs);
System.out.println(songs);
This will give you the list in alphabetical order.
Related
I'm learning Java and trying out stuff. I want to be able to print students' names with their courses and grades. I have written the following classes to achieve that but since I'm a newbie, I'm wondering if I have done it correctly. The code does display what I want but how can I best optimize it?
Subject class:
public class Subject {
private String subjName;
private int subjGrade;
public Subject(String subjName, int subjGrade) {
this.subjName = subjName;
this.subjGrade = subjGrade;
}
public void setName(String name) {
this.subjName = name;
}
public String getName() {
return subjName;
}
public int getGrade(){
return subjGrade;
}
#Override
public String toString() {
return String.format( getName() + ", Grade:" + getGrade());
}
}
StudentSubJGrade class:
import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class StudentSubJGrade {
String name;
Subject[] subjects;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setSubjects(Subject[] subjects) {
this.subjects = subjects;
}
public StudentSubJGrade(String name, Subject[] subjects) {
this.name = name;
this.subjects = subjects;
}
#Override
public String toString() {
return String.format("Name:" + getName() + " Subjects:" + Arrays.toString(subjects));
}
}
I feel I can add the subjects via the ArrayList but couldn't come up with how to do it after hours of trials. How can this be done without using arrays as I have done?
Driver class:
import java.util.ArrayList;
public class StudentSubjGradeDriver {
public static void main(String[] args) {
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<StudentSubJGrade> test2 = new ArrayList<>();
Subject[] subjects = new Subject[3];
subjects[0] = new Subject("Maths",80);
subjects[1] = new Subject("Physic",90);
subjects[2] = new Subject("Chemistry",70);
Subject[] subjects1 = new Subject[4];
subjects1[0] = new Subject("Maths",80);
subjects1[1] = new Subject("Physic",90);
subjects1[2] = new Subject("Chemistry",70);
subjects1[3] = new Subject("Geography",90);
test.add(new StudentSubJGrade("Anita",subjects));
test2.add(new StudentSubJGrade("James",subjects1));
System.out.println(test);
System.out.println(test2);
}
}
After carrying out suggestions, I tried improving on the code by creating the subjects as ArrayLists but I'm having trouble with it:
ArrayList<Subject> subjects;
public StudentSubJGrade(String name, ArrayList<Subject> subjects) {
this.name = name;
this.subjects = subjects;
}
Now in the main method, I tried the following but I'm getting an error:
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<Subject> st = new ArrayList<>();
st.add(new Subject("Maths",90));
test.add("Anita",st);
The problems with your code are that a) you are passing an array to the constructor without copying it, and b) you cannot change the subjects later.
For example, for a) say that you do the following:
Subject[] subjects = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70),
new Subject("Geography",90)
};
StudentSubJGrade student = new StudentSubJGrade("Hassan", subjects );
So far, so good. But now:
subjects[ 0 ] = null;
And suddenly your StudentSubJGrade student object has a null in its subjects.
This effect has to do with arrays being objects (like Student), instead of value types (as in int x = 5), which implies that in your case both references will point to the same array.
Take look here for a demo on shared array objects.
You can avoid this by changing the method setSubjects().
public void setSubjects(Subject[] subjects)
{
this.copySubjects( subjects );
}
private void copySubjects(Subject[] subjects)
{
final int arraySize = subjects.length;
this.subjects = new Subject[ arraySize ];
System.arraycopy( subjects, 0, this.subjects, 0, arraySize );
}
public StudentSubJGrade(String name, Subject[] subjects) {
this.name = name;
this.copySubjects( subjects );
}
If you need to change the subjects later, then you need to change the array inside the class for an ArrayList, and never expose it. You can get the subjects with the toArray() method, and accept an array or an enumeration to load it.
public void clearSubjects()
{
this.subjects.clear();
}
public void addSubjects(Subject[] subjects)
{
this.appendSubjects( subjects );
}
private void appendSubjects(Subject[] subjects)
{
this.subjects.addAll( subjects );
}
public Subject[] getSubjects()
{
return this.subjects.toArray( new Subject[ 0 ] );
}
public StudentSubJGrade(String name, Subject[] subjects)
{
this.name = name;
this.appendSubjects( subjects );
}
private ArrayList<Subject> subjects;
Hope this helps.
You have to use arrays because the StudentSubJGrade constructor expects the second argument to be a Subject[]. However, you can simplify your creation of the arrays:
import java.util.ArrayList;
public class StudentSubjGradeDriver {
public static void main(String[] args) {
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<StudentSubJGrade> test2 = new ArrayList<>();
Subject[] subjects = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70)
};
Subject[] subjects1 = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70),
new Subject("Geography",90)
};
test.add(new StudentSubJGrade("Hassan",subjects));
test2.add(new StudentSubJGrade("James",subjects1));
System.out.println(test);
System.out.println(test2);
}
}
I already filtered a group of object against a specific string entered in the EditText and now I need to sort that list with the position of the specified string, how can I do that?
I am already done this
Filter Function
public void setFilter(String query) {
visibleList = new ArrayList<>();
query = query.toLowerCase(Locale.getDefault());
for (AccountProfile accountProfile : accountProfileList) {
if (accountProfile.getName().toLowerCase(Locale.getDefault())
.contains(query))
visibleList.add(accountProfile);
}
Collections.sort(visibleList, new AccountNameComparator());
}
AccountNameComparator
public class AccountNameComparator implements Comparator<AccountProfile> {
#Override
public int compare(AccountProfile first, AccountProfile second) {
return first.getName().compareTo(second.getName());
}
}
the list is sorted but it is based on the getname() I need to sort the list with specific substring of the getname()
To sort that list with the position of the specified string, you could try something like this:
public class AccountNameComparator implements Comparator<AccountProfile> {
private final String query;
public AccountNameComparator(String query) {
this.query = query;
}
#Override
public int compare(AccountProfile first, AccountProfile second) {
Integer f = first.getName().indexOf(this.query);
Integer s = second.getName().indexOf(this.query);
return f.compareTo(s);
}
}
There is slight change in above answer: like below
public class AccountNameComparator implements Comparator<AccountProfile> {
private final String query;
public AccoluntNameSortComparator(String query) {
this.query = query;
}
#Override
public int compare(AccountProfile first, AccountProfile second) {
String firstName = first.getName().toLowerCase();
String secoundName = second.getName().toLowerCase();
query = query.toLowerCase();
Integer f = firstName.indexOf(query);
Integer s = secoundName.indexOf(query);
return f.compareTo(s);
}
}
This question already has answers here:
How to sort ArrayList while implementing Parcelable
(2 answers)
Closed 6 years ago.
I have categories ArrayList which is passed to a label. The label gets category name and set it.
private List<Category> mCategories;
private LayoutInflater mInflater;
public LeftMenuAdapter(Context context, List<Category> categories) {
mCategories = categories;
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
Category category = mCategories.get(position - 3);
holder.label.setText(category.getName());
Category Class:
public class Category implements Parcelable {
private List<String> images;
private String name;
public List<String> getImages() {
return this.images;
}
public void setImages(List<String> images) {
this.images = images;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
protected Category(Parcel in) {
if (in.readByte() == 0x01) {
images = new ArrayList<String>();
in.readList(images, String.class.getClassLoader());
} else {
images = null;
}
name = in.readString();
}
#Override
public int describeContents() {
return 2;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
if (images == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(images);
}
dest.writeString(name);
}
public static final Parcelable.Creator<Category> CREATOR = new Parcelable.Creator<Category>() {
#Override
public Category createFromParcel(Parcel in) {
return new Category(in);
}
#Override
public Category[] newArray(int size) {
return new Category[size];
}
};
}
I used the Comparator but it says Cannot resolve symbol sort. How can I sort the categories by name?
public class CategoryComparator implements Comparator<Category> {
#Override
public int compare(Category o1, Category o2) {
if(o1.getName()!=null && o2.getName()!=null){
return o1.getName().compareToIgnoreCase(o2.getName());
}else{
return 0;
}
}
}
Define One class likewise,
class SortByNameCategory implements Comparator<Category>{
#Override
public int compare(Category c1, Category c2) {
return (c1.getName() != null ? c1.getName().compareTo(c2.getName())).compareTo(c2.getName() : 0);
}
}
... at somewhere else..
List<Category> listofCategory = new ArrayList<Category>();
// populate this listofCategory as per your wish...
java.util.Collections.sort(listofCategory , new SortByNameCategory()); // this will sort your listofCategory by Category's Name base
You need to create custom comparator
public class CustomComparator implements Comparator<MyObject> {
#Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
}
and compare your objects from arrayList:
Collections.sort(arrayList, new CustomComparator());
You have to implement Comparable interface in your Category class and override the compareTo() method.
So your problem here is sort doesn't know what to do with class.you have to create categories but you have to write a method which tells what exactly has to be sorted .
If your class contains strings then use the comparator and sort it according to starting char or whichever type you like
Similarly with int and everything.
Currently if you call sort on your list it wouldn't know what to do with your class.
I want to sort ArrayList according to artist's name I have used comparator interface but I'm not able to sort the list. So kindly help me to solve the problem. The track data will be read from a file Trackdump. The file would contain one track data per line in the format TITLE/ARTIST/RATING/BPM
Here is the code:
import java.io.*;
import java.util.*;
public class MusicLibrary {
ArrayList<Track> songList = new ArrayList<Track>();
public static void main(String args[]) {
new MusicLibrary().go();
}
public void go() {
System.out.println("go");
getTracks();
System.out.println("Before Sorting:");
System.out.println(songList);
Collections.sort(songList);
System.out.println("Sorted according to Artist's name:");
System.out.println(songList);
}
void getTracks() {
System.out.println("gt");
File file = new File("TrackDump.txt");
try{
BufferedReader readr = new BufferedReader(new FileReader(file));
String line = null;
System.out.println(readr);
while ((line = readr.readLine()) != null) {
System.out.println(line);
addSong(line);
}
}catch(Exception e){
e.printStackTrace();
}
}
void addSong(String lineToParse) {
String[] tokens = lineToParse.split("/");
Track nextSong = new Track(tokens[0], tokens[1], tokens[2], tokens[3]);
songList.add(nextSong);
System.out.println(songList);
}
}
class Track implements Comparator<Track>
{
String title;
String artist;
String rating;
String bpm;
public int compare(Track o1, Track o2) {
return o1.getArtist().compareTo(o2.getArtist());
}
public Track(String a, String t, String r, String b) {
title = t;
artist = a;
rating = r;
bpm = b;
}
public boolean equals(Object aSong) {
return this.equals(aSong);
}
public String getArtist() {
return artist;
}
public String getBpm() {
return bpm;
}
public String getRating() {
return rating;
}
public String getTitle() {
return title;
}
public String toString() {
return title + "-" + artist;
}
}
Trackdump:
Title1/Artist1/8/320
Title2/Artist2/10/48
T5/A7/10/120
Title4/A7/9/240
T7/Artist5/7/320
Title6/Artist6/3/240
T9/A7/1/550
T6/Artist8/5/120
T1/Artist9/5/290
Song2/A0/5/320
Song5/A8/10/320
Song1/A2/6/290
You have to implement Comparable class to your Track class. Not Comparator. Then override compareTo() method. It would look like this:
public class Track implements Comparable<Track> {
// Variables, constructor, getters, setters ...
#Override
public int compareTo(Track other) {
return this.getArtist().compareTo(other.getArtist());
}
}
Finally sort with Collections.sort();
You need to implement the Comparable interface and then you can use Collections.sort().
class Track implements Comparable<Track> {
String title;
String artist;
String rating;
String bpm;
#Override
public int compare(Track other) {
return this.getArtist().compareTo(other.getArtist());
}
...
In theory it would work too when implementing Comparator but then you have to pass a Track object into Collections.sort() to act as the Comparator. But that is a rather weird way of doing it so better use the solution above.
Collections.sort(songList, new Track(null, null, null, null));
I have this class:
public class Friend {
private String name;
private String location;
private String temp;
private String humidity;
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getHumidity() {
return humidity;
}
public void setHumidity(String humidity) {
this.humidity = humidity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
I want to sort a List based on name, location, temp and humidity based on user input.
EDIT:The user specifies by which data member the sorting has to be done.
What is the easiest way to do this?
Thank you.
Because you want to sort them by four different standards, implementing Comparable does not make sense. In this case, you may find that creating different Comparators for each sort-by parameter. However, you could implement Comparable for the most logical sort-by field, such as name. Otherwise, comparators are the way to go.
public class FriendNameComparator extends Comparator<Friend> {
// assuming both are non-null for code simplicity; you may wish to change that
public int compare(Friend f1, Friend f2) {
return f1.getName().compareTo(f2.getName());
}
}
public class FriendLocationComparator extends Comparator<Friend> {
// assuming both are non-null for code simplicity; you may wish to change that
public int compare(Friend f1, Friend f2) {
return f1.getLocation().compareTo(f2.getLocation());
}
}
// and so forth
Then, you can use the sort function of the Collections utility class to sort by the given comparator.
Collections.sort(friendsList, new FriendNameComparator()); // sorts by name
Collections.sort(friendsList, new FriendLocationComparator()); // sorts by location
// etc
Java has a static function called Collections.sort(List, Comparator) which sorts a (generified) List of objects given a custom Comparator which, given two objects of the same type, determines which one is ordered before the other.
Your task is to write a function which creates a Comparator which orders the objects based on its arguments and the user specified sort order. For example:
public Comparator<Friend> getComparator(final String sortBy) {
if ("name".equals(sortBy)) {
return new Comparator<Friend>() {
#Override int compare(Friend f1, Friend f2)
return f1.getName().compareTo(f2.getName());
}
};
} else if ("location".equals(sortBy)) {
return new Comparator<Friend>() {
#Override int compare(Friend f1, Friend f2)
return f1.getLocation().compareTo(f2.getLocation());
}
};
} else if ("temp".equals(sortBy)) {
// ...
} else {
throw new IllegalArgumentException("invalid sort field '" + sortBy + "'");
}
}
List list=new ArrayList();
Use If else if for each criteria:
if(location ){
Collections.sort(list, new Comparator () {
public int compare(YourObject o1, YourObject o2) {
return o1.getLocation().compareTo(o2.getLocation());
}
});
}
} else if(temp ){
........
}
.......