我想根据用户状态对用户列表进行排序,但是顺序必须基于我设置的顺序。
我要设置列表的顺序
订单应为 1、0、5 。我们还应该记住也要订购用户名。
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));
这是用户类别
public class User {
private String username;
private Integer status;
}
应该看起来像这样
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
我不确定是否可以使用 Comparator.comparing ,因为这既不是升序也不是降序。
答案 0 :(得分:9)
一种方法可能是保存所需顺序的列表,并根据其索引对用户进行排序:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
请注意,尽管这种方法对于少量状态(如您当前拥有的状态)应该是合理的,但是如果存在大量状态,并且每个状态都需要执行O(n)搜索,则可能会减慢排序速度时间。一种性能更好的方法(虽然可以说不那么时尚)将是使用地图:
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));
答案 1 :(得分:6)
如果您不介意在项目中使用番石榴,则可以使用import ... from ...
:
Ordering.explicit
如果您还想按名称排序,请添加users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
:
thenComparing
答案 2 :(得分:1)
假设1
,0
和5
将是status
的唯一值,AJNeufeld在their comment中提出了一个很好的观点;他们表示您可以使用方程式将每个值映射为升序。在这种情况下,等式为(x - 1)^2
,其中x
是status
的值:
users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));
如果在调用上述代码段后要打印user
的内容,则会得到:
[用户[用户名= A,状态= 1],用户[用户名= D,状态= 1],用户[用户名= C,状态= 0],用户[用户名= F,状态= 0],用户[用户名= B,状态= 5],用户[用户名= E,状态= 5]]
答案 3 :(得分:0)
您可以尝试逐步进行此操作
import csv, json,os
x = """[
.... I have data here
]"""
img_data = json.loads(x)
#Uname is going to hold the current user name
Uname=os.getlogin()
# I want to use %USERNAME% here instead of each time changing the qid for different users
##Ensure this folder exists
outputFile = open("C:/Users/"+Uname+"/Desktop/JSON/imageData1.csv", "w")
csvwriter = csv.writer(outputFile)
csvwriter.writerow( ["fileName", "path", "annotatedImagePath", "resultFilePath", "numberOfDetectedObject", "numberOfQualifiedObject", "analysisDate", "hasFailed"] )
for row in img_data:
csvwriter.writerow( [row["fileName"], row["path"], row["annotatedImagePath"], row["resultFilePath"], row["numberOfDetectedObject"], row["numberOfQualifiedObject"], row["analysisDate"], row["hasFailed"] ] )
outputFile.close()
答案 4 :(得分:0)
如前所述,您需要自定义排序,这意味着您需要在HashMap << strong> Status,Rank >>或一种简单的方法中定义排序的某个地方,再添加一个属性,例如 Integer rank; ,然后您可以根据状态属性的排序来定义排名,例如says users.add(new User(“ A”,1,0));在这里,状态1是最排序的,其等级= 0。然后,您可以在等级属性上使用 Comparator 。
例如:
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;
}
}
比较器类:
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;
}
}
主类:
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);
}
}