Sort with one element at the end

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have a list of objects and I want to sort it alphabetically by an attribute. But I want to add an exception rule if this attribute matches a specific string. For example:
public class Car
String name;
List<Car> cars = asList(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars
.stream
.sorted(Comparator.comparing(Car::getName))
.collect(Collectors.toList());
If cars.name == "Unassigned" then this car should remain at the end of the list and the result would be:
[Car<Honda>, Car<Nissan>, Car<Yamaha>, Car<Unassigned>]
java sorting java-8 java-stream
add a comment |
I have a list of objects and I want to sort it alphabetically by an attribute. But I want to add an exception rule if this attribute matches a specific string. For example:
public class Car
String name;
List<Car> cars = asList(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars
.stream
.sorted(Comparator.comparing(Car::getName))
.collect(Collectors.toList());
If cars.name == "Unassigned" then this car should remain at the end of the list and the result would be:
[Car<Honda>, Car<Nissan>, Car<Yamaha>, Car<Unassigned>]
java sorting java-8 java-stream
add a comment |
I have a list of objects and I want to sort it alphabetically by an attribute. But I want to add an exception rule if this attribute matches a specific string. For example:
public class Car
String name;
List<Car> cars = asList(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars
.stream
.sorted(Comparator.comparing(Car::getName))
.collect(Collectors.toList());
If cars.name == "Unassigned" then this car should remain at the end of the list and the result would be:
[Car<Honda>, Car<Nissan>, Car<Yamaha>, Car<Unassigned>]
java sorting java-8 java-stream
I have a list of objects and I want to sort it alphabetically by an attribute. But I want to add an exception rule if this attribute matches a specific string. For example:
public class Car
String name;
List<Car> cars = asList(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars
.stream
.sorted(Comparator.comparing(Car::getName))
.collect(Collectors.toList());
If cars.name == "Unassigned" then this car should remain at the end of the list and the result would be:
[Car<Honda>, Car<Nissan>, Car<Yamaha>, Car<Unassigned>]
java sorting java-8 java-stream
java sorting java-8 java-stream
edited Mar 11 at 14:01
Lii
7,24344163
7,24344163
asked Mar 11 at 13:26
bpereirabpereira
419417
419417
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
There are a lot of things going on here. First I am using Comparator.comparing(Function, Comparator); then (String x) -> x.equals("Unassigned") which actually compares a Boolean (that is Comparable); then the fact that (String x) is used - as this type witness is used to correctly infer the types...
1
Clever! But I think that the trick withcomparing((String x) -> x.equals("Unassigned"))is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...
– Lii
Mar 11 at 14:32
1
@Lii which is left as an exercise to the reader... I mentioned it sorts aBoolean(that isComparable), that should provide the proper direction.
– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
add a comment |
The most direct and and easy-to-read solution is probably to write a custom comparator that implements your sorting logic.
You can still use the Comparator.comparing method to make it a bit prittier, though:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) ->
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
))
.collect(Collectors.toList());
Also, it's good style to use a named constant for special values like your "Unassigned".
Also, note that if you don't need to keep the unsorted cars list, then you can sort that list in place instead of using a stream:
cars.sort(UNASSIGNED_COMPARATOR);
add a comment |
One way to possibly do that would be using partitioning as:
Map<Boolean, List<Car>> partitionedCars = cars
.stream()
.collect(Collectors.partitioningBy(a -> a.getName().equals("Unassigned")));
List<Car> sortedCars = Stream.concat(partitionedCars.get(Boolean.FALSE).stream()
.sorted(Comparator.comparing(Car::getName)), partitionedCars.get(Boolean.TRUE).stream())
.collect(Collectors.toList());
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
add a comment |
You could just replace "Unassigned" with an end-of-alphabet string in your comparator.
Comparator.comparing(car -> car.getName().equals("Unassigned") ? "ZZZ" : car.getName())
add a comment |
Alternatively, just remove all instances of "Unassigned" and add however many to the end of the List after. For example:
int numberOfUnassigned = 0;
for (Iterator<Car> iterator = sortedCars.iterator(); iterator.hasNext();)
String str = iterator.next().getName();
if (str.equals("Unassigned"))
iterator.remove();
numberOfUnassigned++;
And then add the number of numberOfUnassigned to the end.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55102884%2fsort-with-one-element-at-the-end%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
There are a lot of things going on here. First I am using Comparator.comparing(Function, Comparator); then (String x) -> x.equals("Unassigned") which actually compares a Boolean (that is Comparable); then the fact that (String x) is used - as this type witness is used to correctly infer the types...
1
Clever! But I think that the trick withcomparing((String x) -> x.equals("Unassigned"))is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...
– Lii
Mar 11 at 14:32
1
@Lii which is left as an exercise to the reader... I mentioned it sorts aBoolean(that isComparable), that should provide the proper direction.
– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
add a comment |
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
There are a lot of things going on here. First I am using Comparator.comparing(Function, Comparator); then (String x) -> x.equals("Unassigned") which actually compares a Boolean (that is Comparable); then the fact that (String x) is used - as this type witness is used to correctly infer the types...
1
Clever! But I think that the trick withcomparing((String x) -> x.equals("Unassigned"))is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...
– Lii
Mar 11 at 14:32
1
@Lii which is left as an exercise to the reader... I mentioned it sorts aBoolean(that isComparable), that should provide the proper direction.
– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
add a comment |
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
There are a lot of things going on here. First I am using Comparator.comparing(Function, Comparator); then (String x) -> x.equals("Unassigned") which actually compares a Boolean (that is Comparable); then the fact that (String x) is used - as this type witness is used to correctly infer the types...
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
There are a lot of things going on here. First I am using Comparator.comparing(Function, Comparator); then (String x) -> x.equals("Unassigned") which actually compares a Boolean (that is Comparable); then the fact that (String x) is used - as this type witness is used to correctly infer the types...
edited Mar 11 at 13:58
answered Mar 11 at 13:33
EugeneEugene
72.4k9103172
72.4k9103172
1
Clever! But I think that the trick withcomparing((String x) -> x.equals("Unassigned"))is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...
– Lii
Mar 11 at 14:32
1
@Lii which is left as an exercise to the reader... I mentioned it sorts aBoolean(that isComparable), that should provide the proper direction.
– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
add a comment |
1
Clever! But I think that the trick withcomparing((String x) -> x.equals("Unassigned"))is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...
– Lii
Mar 11 at 14:32
1
@Lii which is left as an exercise to the reader... I mentioned it sorts aBoolean(that isComparable), that should provide the proper direction.
– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
1
1
Clever! But I think that the trick with
comparing((String x) -> x.equals("Unassigned")) is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...– Lii
Mar 11 at 14:32
Clever! But I think that the trick with
comparing((String x) -> x.equals("Unassigned")) is so tricky that it warrants an explanatory comment in the code, it it where to be used in production...– Lii
Mar 11 at 14:32
1
1
@Lii which is left as an exercise to the reader... I mentioned it sorts a
Boolean (that is Comparable), that should provide the proper direction.– Eugene
Mar 11 at 14:33
@Lii which is left as an exercise to the reader... I mentioned it sorts a
Boolean (that is Comparable), that should provide the proper direction.– Eugene
Mar 11 at 14:33
Clever indeed.
– user7
Mar 13 at 4:07
Clever indeed.
– user7
Mar 13 at 4:07
add a comment |
The most direct and and easy-to-read solution is probably to write a custom comparator that implements your sorting logic.
You can still use the Comparator.comparing method to make it a bit prittier, though:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) ->
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
))
.collect(Collectors.toList());
Also, it's good style to use a named constant for special values like your "Unassigned".
Also, note that if you don't need to keep the unsorted cars list, then you can sort that list in place instead of using a stream:
cars.sort(UNASSIGNED_COMPARATOR);
add a comment |
The most direct and and easy-to-read solution is probably to write a custom comparator that implements your sorting logic.
You can still use the Comparator.comparing method to make it a bit prittier, though:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) ->
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
))
.collect(Collectors.toList());
Also, it's good style to use a named constant for special values like your "Unassigned".
Also, note that if you don't need to keep the unsorted cars list, then you can sort that list in place instead of using a stream:
cars.sort(UNASSIGNED_COMPARATOR);
add a comment |
The most direct and and easy-to-read solution is probably to write a custom comparator that implements your sorting logic.
You can still use the Comparator.comparing method to make it a bit prittier, though:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) ->
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
))
.collect(Collectors.toList());
Also, it's good style to use a named constant for special values like your "Unassigned".
Also, note that if you don't need to keep the unsorted cars list, then you can sort that list in place instead of using a stream:
cars.sort(UNASSIGNED_COMPARATOR);
The most direct and and easy-to-read solution is probably to write a custom comparator that implements your sorting logic.
You can still use the Comparator.comparing method to make it a bit prittier, though:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) ->
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
))
.collect(Collectors.toList());
Also, it's good style to use a named constant for special values like your "Unassigned".
Also, note that if you don't need to keep the unsorted cars list, then you can sort that list in place instead of using a stream:
cars.sort(UNASSIGNED_COMPARATOR);
edited Mar 19 at 8:38
answered Mar 11 at 13:58
LiiLii
7,24344163
7,24344163
add a comment |
add a comment |
One way to possibly do that would be using partitioning as:
Map<Boolean, List<Car>> partitionedCars = cars
.stream()
.collect(Collectors.partitioningBy(a -> a.getName().equals("Unassigned")));
List<Car> sortedCars = Stream.concat(partitionedCars.get(Boolean.FALSE).stream()
.sorted(Comparator.comparing(Car::getName)), partitionedCars.get(Boolean.TRUE).stream())
.collect(Collectors.toList());
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
add a comment |
One way to possibly do that would be using partitioning as:
Map<Boolean, List<Car>> partitionedCars = cars
.stream()
.collect(Collectors.partitioningBy(a -> a.getName().equals("Unassigned")));
List<Car> sortedCars = Stream.concat(partitionedCars.get(Boolean.FALSE).stream()
.sorted(Comparator.comparing(Car::getName)), partitionedCars.get(Boolean.TRUE).stream())
.collect(Collectors.toList());
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
add a comment |
One way to possibly do that would be using partitioning as:
Map<Boolean, List<Car>> partitionedCars = cars
.stream()
.collect(Collectors.partitioningBy(a -> a.getName().equals("Unassigned")));
List<Car> sortedCars = Stream.concat(partitionedCars.get(Boolean.FALSE).stream()
.sorted(Comparator.comparing(Car::getName)), partitionedCars.get(Boolean.TRUE).stream())
.collect(Collectors.toList());
One way to possibly do that would be using partitioning as:
Map<Boolean, List<Car>> partitionedCars = cars
.stream()
.collect(Collectors.partitioningBy(a -> a.getName().equals("Unassigned")));
List<Car> sortedCars = Stream.concat(partitionedCars.get(Boolean.FALSE).stream()
.sorted(Comparator.comparing(Car::getName)), partitionedCars.get(Boolean.TRUE).stream())
.collect(Collectors.toList());
edited Mar 12 at 0:43
answered Mar 11 at 13:32
NamanNaman
45.8k11102204
45.8k11102204
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
add a comment |
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
4
4
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
this is ingenious, but wasteful or resources... of course.
– Eugene
Mar 11 at 14:04
add a comment |
You could just replace "Unassigned" with an end-of-alphabet string in your comparator.
Comparator.comparing(car -> car.getName().equals("Unassigned") ? "ZZZ" : car.getName())
add a comment |
You could just replace "Unassigned" with an end-of-alphabet string in your comparator.
Comparator.comparing(car -> car.getName().equals("Unassigned") ? "ZZZ" : car.getName())
add a comment |
You could just replace "Unassigned" with an end-of-alphabet string in your comparator.
Comparator.comparing(car -> car.getName().equals("Unassigned") ? "ZZZ" : car.getName())
You could just replace "Unassigned" with an end-of-alphabet string in your comparator.
Comparator.comparing(car -> car.getName().equals("Unassigned") ? "ZZZ" : car.getName())
answered Mar 11 at 13:52
MikeFHayMikeFHay
3,25032035
3,25032035
add a comment |
add a comment |
Alternatively, just remove all instances of "Unassigned" and add however many to the end of the List after. For example:
int numberOfUnassigned = 0;
for (Iterator<Car> iterator = sortedCars.iterator(); iterator.hasNext();)
String str = iterator.next().getName();
if (str.equals("Unassigned"))
iterator.remove();
numberOfUnassigned++;
And then add the number of numberOfUnassigned to the end.
add a comment |
Alternatively, just remove all instances of "Unassigned" and add however many to the end of the List after. For example:
int numberOfUnassigned = 0;
for (Iterator<Car> iterator = sortedCars.iterator(); iterator.hasNext();)
String str = iterator.next().getName();
if (str.equals("Unassigned"))
iterator.remove();
numberOfUnassigned++;
And then add the number of numberOfUnassigned to the end.
add a comment |
Alternatively, just remove all instances of "Unassigned" and add however many to the end of the List after. For example:
int numberOfUnassigned = 0;
for (Iterator<Car> iterator = sortedCars.iterator(); iterator.hasNext();)
String str = iterator.next().getName();
if (str.equals("Unassigned"))
iterator.remove();
numberOfUnassigned++;
And then add the number of numberOfUnassigned to the end.
Alternatively, just remove all instances of "Unassigned" and add however many to the end of the List after. For example:
int numberOfUnassigned = 0;
for (Iterator<Car> iterator = sortedCars.iterator(); iterator.hasNext();)
String str = iterator.next().getName();
if (str.equals("Unassigned"))
iterator.remove();
numberOfUnassigned++;
And then add the number of numberOfUnassigned to the end.
answered Mar 11 at 14:09
achAmháinachAmháin
3,2423932
3,2423932
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55102884%2fsort-with-one-element-at-the-end%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown