Java 8 - customised sort based on specific order
I would like to sort the user list based on their status but the order must be based on the order that I set.
I want to set the order of list,
The order should be 1, 0 , 5. We should also keep in mind to order the username as well.
List<User> users = new ArrayList();
users.add(new User("A", 1));
users.add(new User("B", 5));
users.add(new User("C", 0));
users.add(new User("D", 1));
users.add(new User("E", 5));
users.add(new User("F", 0));
Here's the user class
public class User {
private String username;
private Integer status;
}
It should look like this
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
I not sure if it's possible to use Comparator.comparing, since this one is neither ascending nor descending order.
java sorting java-8 comparator
|
show 3 more comments
I would like to sort the user list based on their status but the order must be based on the order that I set.
I want to set the order of list,
The order should be 1, 0 , 5. We should also keep in mind to order the username as well.
List<User> users = new ArrayList();
users.add(new User("A", 1));
users.add(new User("B", 5));
users.add(new User("C", 0));
users.add(new User("D", 1));
users.add(new User("E", 5));
users.add(new User("F", 0));
Here's the user class
public class User {
private String username;
private Integer status;
}
It should look like this
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
I not sure if it's possible to use Comparator.comparing, since this one is neither ascending nor descending order.
java sorting java-8 comparator
2
Yes,Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try
– MadProgrammer
Nov 12 '18 at 4:02
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
1
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
1
@KennethCCompator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted
– MadProgrammer
Nov 12 '18 at 4:16
1
@KennethC Take a look at the documentation ofComparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).
– Slaw
Nov 12 '18 at 4:17
|
show 3 more comments
I would like to sort the user list based on their status but the order must be based on the order that I set.
I want to set the order of list,
The order should be 1, 0 , 5. We should also keep in mind to order the username as well.
List<User> users = new ArrayList();
users.add(new User("A", 1));
users.add(new User("B", 5));
users.add(new User("C", 0));
users.add(new User("D", 1));
users.add(new User("E", 5));
users.add(new User("F", 0));
Here's the user class
public class User {
private String username;
private Integer status;
}
It should look like this
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
I not sure if it's possible to use Comparator.comparing, since this one is neither ascending nor descending order.
java sorting java-8 comparator
I would like to sort the user list based on their status but the order must be based on the order that I set.
I want to set the order of list,
The order should be 1, 0 , 5. We should also keep in mind to order the username as well.
List<User> users = new ArrayList();
users.add(new User("A", 1));
users.add(new User("B", 5));
users.add(new User("C", 0));
users.add(new User("D", 1));
users.add(new User("E", 5));
users.add(new User("F", 0));
Here's the user class
public class User {
private String username;
private Integer status;
}
It should look like this
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
I not sure if it's possible to use Comparator.comparing, since this one is neither ascending nor descending order.
java sorting java-8 comparator
java sorting java-8 comparator
edited Nov 12 '18 at 4:22
Mureinik
180k22130198
180k22130198
asked Nov 12 '18 at 3:59
KennethC
271215
271215
2
Yes,Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try
– MadProgrammer
Nov 12 '18 at 4:02
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
1
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
1
@KennethCCompator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted
– MadProgrammer
Nov 12 '18 at 4:16
1
@KennethC Take a look at the documentation ofComparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).
– Slaw
Nov 12 '18 at 4:17
|
show 3 more comments
2
Yes,Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try
– MadProgrammer
Nov 12 '18 at 4:02
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
1
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
1
@KennethCCompator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted
– MadProgrammer
Nov 12 '18 at 4:16
1
@KennethC Take a look at the documentation ofComparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).
– Slaw
Nov 12 '18 at 4:17
2
2
Yes,
Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try– MadProgrammer
Nov 12 '18 at 4:02
Yes,
Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try– MadProgrammer
Nov 12 '18 at 4:02
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
1
1
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
1
1
@KennethC
Compator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted– MadProgrammer
Nov 12 '18 at 4:16
@KennethC
Compator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted– MadProgrammer
Nov 12 '18 at 4:16
1
1
@KennethC Take a look at the documentation of
Comparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).– Slaw
Nov 12 '18 at 4:17
@KennethC Take a look at the documentation of
Comparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).– Slaw
Nov 12 '18 at 4:17
|
show 3 more comments
5 Answers
5
active
oldest
votes
One approach could be to hold a list with the order you want and sort the users according to its index:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
add a comment |
If you don't mind using Guava in your project, you can use Ordering.explicit
:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
If you want to sort by name also, then add thenComparing
:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
this is how I would do it, mainly because thatexplicit
is well such a clear and "explicit" name
– Eugene
Nov 12 '18 at 4:26
add a comment |
Assuming 1
, 0
, and 5
will be the only values of status
, AJNeufeld made an excellent point in their comment; they stated that you can use an equation to map each value into an ascending order. In this case, the equation would be (x - 1)^2
where x
is the value of status
:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
If you were to print the contents of user
after calling the above snippet, you'd get:
[User [username=A, status=1], User [username=D, status=1], User [username=C, status=0], User [username=F, status=0], User [username=B, status=5], User [username=E, status=5]]
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
@ZhekaKozlovv^1
…
– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlovvalue ^ 1
is even simpler thanMath.abs(value - 1)
(the difference is not as big as the difference of both toMath.pow
, though).
– Holger
Nov 12 '18 at 12:27
@Holger0^1 < 1^1
(should be greater)
– ZhekaKozlov
Nov 12 '18 at 12:29
|
show 2 more comments
You can try to do this step by step
//order define here
List<Integer> statusOrder= Arrays.asList(1,0,5,2);
//define sort by status
Comparator<User> byStatus = (u1, u2) -> {
return Integer.compare(statusOrder.indexOf(u1.getStatus()), statusOrder.indexOf(u2.getStatus()));
};
//define sort by name
Comparator<User> byName = Comparator.comparing(User::getUsername);
//actualy sort
users.sort(byStatus.thenComparing(byName));
add a comment |
As you have mentioned you need custom ordering and that means you need to define somewhere that ordering either in HashMap<Status,Rank>> or one simple way add one more attribute say Integer rank; and you can define the rank based on your ordering for status attribute like say users.add(new User("A", 1,0)); here status 1 is sortest in order and its rank=0. And then you can use Comparator on rank attribute.
For e.g :
public class User {
public String username;
public Integer status;
public Integer rank;
public User(String username, Integer status, Integer rank)
{
this.username = username;
this.status = status;
this.rank = rank;
}
}
Comparator class :
class SortByRank implements Comparator<User>
{
// Used for sorting in ascending order of
// rank number
public int compare(User a, User b)
{
return a.rank - b.rank;
}
}
Main Class :
class Main
{
public static void main (String args)
{
List<User> users = new ArrayList();
users.add(new User("A", 1, 0));
users.add(new User("B", 5, 2));
users.add(new User("C", 0, 1));
users.add(new User("D", 1, 0));
users.add(new User("E", 5, 2));
users.add(new User("F", 0, 1));
System.out.println("Unsorted");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
Collections.sort(users, new SortByRank());
System.out.println("nSorted by Rank");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
}
}
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%2f53255793%2fjava-8-customised-sort-based-on-specific-order%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
One approach could be to hold a list with the order you want and sort the users according to its index:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
add a comment |
One approach could be to hold a list with the order you want and sort the users according to its index:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
add a comment |
One approach could be to hold a list with the order you want and sort the users according to its index:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
One approach could be to hold a list with the order you want and sort the users according to its index:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Note that while this approach should be reasonable for a small number of statuses (like you currently have), it may slow down sorting if there are a large number of statuses and you need to do perform an O(n) search each time. A better performing approach (albeit arguably not as sleek), would be to use a map:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
edited Dec 10 '18 at 6:37
answered Nov 12 '18 at 4:20
Mureinik
180k22130198
180k22130198
add a comment |
add a comment |
If you don't mind using Guava in your project, you can use Ordering.explicit
:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
If you want to sort by name also, then add thenComparing
:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
this is how I would do it, mainly because thatexplicit
is well such a clear and "explicit" name
– Eugene
Nov 12 '18 at 4:26
add a comment |
If you don't mind using Guava in your project, you can use Ordering.explicit
:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
If you want to sort by name also, then add thenComparing
:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
this is how I would do it, mainly because thatexplicit
is well such a clear and "explicit" name
– Eugene
Nov 12 '18 at 4:26
add a comment |
If you don't mind using Guava in your project, you can use Ordering.explicit
:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
If you want to sort by name also, then add thenComparing
:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
If you don't mind using Guava in your project, you can use Ordering.explicit
:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
If you want to sort by name also, then add thenComparing
:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
answered Nov 12 '18 at 4:09
ZhekaKozlov
14.7k866111
14.7k866111
this is how I would do it, mainly because thatexplicit
is well such a clear and "explicit" name
– Eugene
Nov 12 '18 at 4:26
add a comment |
this is how I would do it, mainly because thatexplicit
is well such a clear and "explicit" name
– Eugene
Nov 12 '18 at 4:26
this is how I would do it, mainly because that
explicit
is well such a clear and "explicit" name– Eugene
Nov 12 '18 at 4:26
this is how I would do it, mainly because that
explicit
is well such a clear and "explicit" name– Eugene
Nov 12 '18 at 4:26
add a comment |
Assuming 1
, 0
, and 5
will be the only values of status
, AJNeufeld made an excellent point in their comment; they stated that you can use an equation to map each value into an ascending order. In this case, the equation would be (x - 1)^2
where x
is the value of status
:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
If you were to print the contents of user
after calling the above snippet, you'd get:
[User [username=A, status=1], User [username=D, status=1], User [username=C, status=0], User [username=F, status=0], User [username=B, status=5], User [username=E, status=5]]
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
@ZhekaKozlovv^1
…
– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlovvalue ^ 1
is even simpler thanMath.abs(value - 1)
(the difference is not as big as the difference of both toMath.pow
, though).
– Holger
Nov 12 '18 at 12:27
@Holger0^1 < 1^1
(should be greater)
– ZhekaKozlov
Nov 12 '18 at 12:29
|
show 2 more comments
Assuming 1
, 0
, and 5
will be the only values of status
, AJNeufeld made an excellent point in their comment; they stated that you can use an equation to map each value into an ascending order. In this case, the equation would be (x - 1)^2
where x
is the value of status
:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
If you were to print the contents of user
after calling the above snippet, you'd get:
[User [username=A, status=1], User [username=D, status=1], User [username=C, status=0], User [username=F, status=0], User [username=B, status=5], User [username=E, status=5]]
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
@ZhekaKozlovv^1
…
– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlovvalue ^ 1
is even simpler thanMath.abs(value - 1)
(the difference is not as big as the difference of both toMath.pow
, though).
– Holger
Nov 12 '18 at 12:27
@Holger0^1 < 1^1
(should be greater)
– ZhekaKozlov
Nov 12 '18 at 12:29
|
show 2 more comments
Assuming 1
, 0
, and 5
will be the only values of status
, AJNeufeld made an excellent point in their comment; they stated that you can use an equation to map each value into an ascending order. In this case, the equation would be (x - 1)^2
where x
is the value of status
:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
If you were to print the contents of user
after calling the above snippet, you'd get:
[User [username=A, status=1], User [username=D, status=1], User [username=C, status=0], User [username=F, status=0], User [username=B, status=5], User [username=E, status=5]]
Assuming 1
, 0
, and 5
will be the only values of status
, AJNeufeld made an excellent point in their comment; they stated that you can use an equation to map each value into an ascending order. In this case, the equation would be (x - 1)^2
where x
is the value of status
:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
If you were to print the contents of user
after calling the above snippet, you'd get:
[User [username=A, status=1], User [username=D, status=1], User [username=C, status=0], User [username=F, status=0], User [username=B, status=5], User [username=E, status=5]]
answered Nov 12 '18 at 4:22
Jacob G.
15.2k52162
15.2k52162
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
@ZhekaKozlovv^1
…
– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlovvalue ^ 1
is even simpler thanMath.abs(value - 1)
(the difference is not as big as the difference of both toMath.pow
, though).
– Holger
Nov 12 '18 at 12:27
@Holger0^1 < 1^1
(should be greater)
– ZhekaKozlov
Nov 12 '18 at 12:29
|
show 2 more comments
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
@ZhekaKozlovv^1
…
– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlovvalue ^ 1
is even simpler thanMath.abs(value - 1)
(the difference is not as big as the difference of both toMath.pow
, though).
– Holger
Nov 12 '18 at 12:27
@Holger0^1 < 1^1
(should be greater)
– ZhekaKozlov
Nov 12 '18 at 12:29
1
1
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
Why not just |x - 1|?
– ZhekaKozlov
Nov 12 '18 at 5:58
1
1
@ZhekaKozlov
v^1
…– Holger
Nov 12 '18 at 10:34
@ZhekaKozlov
v^1
…– Holger
Nov 12 '18 at 10:34
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@Holger Excuse me?
– ZhekaKozlov
Nov 12 '18 at 12:26
@ZhekaKozlov
value ^ 1
is even simpler than Math.abs(value - 1)
(the difference is not as big as the difference of both to Math.pow
, though).– Holger
Nov 12 '18 at 12:27
@ZhekaKozlov
value ^ 1
is even simpler than Math.abs(value - 1)
(the difference is not as big as the difference of both to Math.pow
, though).– Holger
Nov 12 '18 at 12:27
@Holger
0^1 < 1^1
(should be greater)– ZhekaKozlov
Nov 12 '18 at 12:29
@Holger
0^1 < 1^1
(should be greater)– ZhekaKozlov
Nov 12 '18 at 12:29
|
show 2 more comments
You can try to do this step by step
//order define here
List<Integer> statusOrder= Arrays.asList(1,0,5,2);
//define sort by status
Comparator<User> byStatus = (u1, u2) -> {
return Integer.compare(statusOrder.indexOf(u1.getStatus()), statusOrder.indexOf(u2.getStatus()));
};
//define sort by name
Comparator<User> byName = Comparator.comparing(User::getUsername);
//actualy sort
users.sort(byStatus.thenComparing(byName));
add a comment |
You can try to do this step by step
//order define here
List<Integer> statusOrder= Arrays.asList(1,0,5,2);
//define sort by status
Comparator<User> byStatus = (u1, u2) -> {
return Integer.compare(statusOrder.indexOf(u1.getStatus()), statusOrder.indexOf(u2.getStatus()));
};
//define sort by name
Comparator<User> byName = Comparator.comparing(User::getUsername);
//actualy sort
users.sort(byStatus.thenComparing(byName));
add a comment |
You can try to do this step by step
//order define here
List<Integer> statusOrder= Arrays.asList(1,0,5,2);
//define sort by status
Comparator<User> byStatus = (u1, u2) -> {
return Integer.compare(statusOrder.indexOf(u1.getStatus()), statusOrder.indexOf(u2.getStatus()));
};
//define sort by name
Comparator<User> byName = Comparator.comparing(User::getUsername);
//actualy sort
users.sort(byStatus.thenComparing(byName));
You can try to do this step by step
//order define here
List<Integer> statusOrder= Arrays.asList(1,0,5,2);
//define sort by status
Comparator<User> byStatus = (u1, u2) -> {
return Integer.compare(statusOrder.indexOf(u1.getStatus()), statusOrder.indexOf(u2.getStatus()));
};
//define sort by name
Comparator<User> byName = Comparator.comparing(User::getUsername);
//actualy sort
users.sort(byStatus.thenComparing(byName));
answered Nov 12 '18 at 4:26
Dang Nguyen
599221
599221
add a comment |
add a comment |
As you have mentioned you need custom ordering and that means you need to define somewhere that ordering either in HashMap<Status,Rank>> or one simple way add one more attribute say Integer rank; and you can define the rank based on your ordering for status attribute like say users.add(new User("A", 1,0)); here status 1 is sortest in order and its rank=0. And then you can use Comparator on rank attribute.
For e.g :
public class User {
public String username;
public Integer status;
public Integer rank;
public User(String username, Integer status, Integer rank)
{
this.username = username;
this.status = status;
this.rank = rank;
}
}
Comparator class :
class SortByRank implements Comparator<User>
{
// Used for sorting in ascending order of
// rank number
public int compare(User a, User b)
{
return a.rank - b.rank;
}
}
Main Class :
class Main
{
public static void main (String args)
{
List<User> users = new ArrayList();
users.add(new User("A", 1, 0));
users.add(new User("B", 5, 2));
users.add(new User("C", 0, 1));
users.add(new User("D", 1, 0));
users.add(new User("E", 5, 2));
users.add(new User("F", 0, 1));
System.out.println("Unsorted");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
Collections.sort(users, new SortByRank());
System.out.println("nSorted by Rank");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
}
}
add a comment |
As you have mentioned you need custom ordering and that means you need to define somewhere that ordering either in HashMap<Status,Rank>> or one simple way add one more attribute say Integer rank; and you can define the rank based on your ordering for status attribute like say users.add(new User("A", 1,0)); here status 1 is sortest in order and its rank=0. And then you can use Comparator on rank attribute.
For e.g :
public class User {
public String username;
public Integer status;
public Integer rank;
public User(String username, Integer status, Integer rank)
{
this.username = username;
this.status = status;
this.rank = rank;
}
}
Comparator class :
class SortByRank implements Comparator<User>
{
// Used for sorting in ascending order of
// rank number
public int compare(User a, User b)
{
return a.rank - b.rank;
}
}
Main Class :
class Main
{
public static void main (String args)
{
List<User> users = new ArrayList();
users.add(new User("A", 1, 0));
users.add(new User("B", 5, 2));
users.add(new User("C", 0, 1));
users.add(new User("D", 1, 0));
users.add(new User("E", 5, 2));
users.add(new User("F", 0, 1));
System.out.println("Unsorted");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
Collections.sort(users, new SortByRank());
System.out.println("nSorted by Rank");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
}
}
add a comment |
As you have mentioned you need custom ordering and that means you need to define somewhere that ordering either in HashMap<Status,Rank>> or one simple way add one more attribute say Integer rank; and you can define the rank based on your ordering for status attribute like say users.add(new User("A", 1,0)); here status 1 is sortest in order and its rank=0. And then you can use Comparator on rank attribute.
For e.g :
public class User {
public String username;
public Integer status;
public Integer rank;
public User(String username, Integer status, Integer rank)
{
this.username = username;
this.status = status;
this.rank = rank;
}
}
Comparator class :
class SortByRank implements Comparator<User>
{
// Used for sorting in ascending order of
// rank number
public int compare(User a, User b)
{
return a.rank - b.rank;
}
}
Main Class :
class Main
{
public static void main (String args)
{
List<User> users = new ArrayList();
users.add(new User("A", 1, 0));
users.add(new User("B", 5, 2));
users.add(new User("C", 0, 1));
users.add(new User("D", 1, 0));
users.add(new User("E", 5, 2));
users.add(new User("F", 0, 1));
System.out.println("Unsorted");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
Collections.sort(users, new SortByRank());
System.out.println("nSorted by Rank");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
}
}
As you have mentioned you need custom ordering and that means you need to define somewhere that ordering either in HashMap<Status,Rank>> or one simple way add one more attribute say Integer rank; and you can define the rank based on your ordering for status attribute like say users.add(new User("A", 1,0)); here status 1 is sortest in order and its rank=0. And then you can use Comparator on rank attribute.
For e.g :
public class User {
public String username;
public Integer status;
public Integer rank;
public User(String username, Integer status, Integer rank)
{
this.username = username;
this.status = status;
this.rank = rank;
}
}
Comparator class :
class SortByRank implements Comparator<User>
{
// Used for sorting in ascending order of
// rank number
public int compare(User a, User b)
{
return a.rank - b.rank;
}
}
Main Class :
class Main
{
public static void main (String args)
{
List<User> users = new ArrayList();
users.add(new User("A", 1, 0));
users.add(new User("B", 5, 2));
users.add(new User("C", 0, 1));
users.add(new User("D", 1, 0));
users.add(new User("E", 5, 2));
users.add(new User("F", 0, 1));
System.out.println("Unsorted");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
Collections.sort(users, new SortByRank());
System.out.println("nSorted by Rank");
for (int i=0; i<users.size(); i++)
System.out.print(users.get(i).username);
}
}
edited Nov 12 '18 at 4:36
answered Nov 12 '18 at 4:28
apandey846
8441019
8441019
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53255793%2fjava-8-customised-sort-based-on-specific-order%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
2
Yes,
Comparator
can deal with, it just needs to return +1/-1/0 based on the comparison of the two values supplied. Best bet is to just give it a try– MadProgrammer
Nov 12 '18 at 4:02
if 1,0,5 is the only status numbers, then you can easily order it using comparator.
– Abhi
Nov 12 '18 at 4:04
1
Subtract 1, then square. 1,0,5 -> 0, 1, 16 ... which is easy to sort
– AJNeufeld
Nov 12 '18 at 4:06
1
@KennethC
Compator
just returns a negative or positive or zero value based on the result of the comparison and the order you want the values to be sorted– MadProgrammer
Nov 12 '18 at 4:16
1
@KennethC Take a look at the documentation of
Comparator.compare
to see what the different return values mean (negative means less than, zero means equal to, positive means greater than).– Slaw
Nov 12 '18 at 4:17