考慮下面的 dto 類 -
public class RoleDto {
private String name;
RoleDto(String name) {
this.name = name;
}
}
它的實體將包含以下名稱 -
Business Practitioner - Expert
Developer - Expert
Developer - Master
Business Practitioner - Master
Business Practitioner
Developer
Developer - Professional
Business Practitioner - Professional
我想對實體進行排序,以便順序為 -
Business Practitioner - Expert
Business Practitioner - Master
Business Practitioner - Professional
Business Practitioner
Developer - Expert
Developer - Master
Developer - Professional
Developer
我使用了下面的代碼 -
ArrayList<RoleDto> roles = new ArrayList<>();
roles.add(new RoleDto("Business Practitioner - Expert"));
roles.add(new RoleDto("Developer - Expert"));
roles.add(new RoleDto("Developer - Master"));
roles.add(new RoleDto("Business Practitioner - Master"));
roles.add(new RoleDto("Business Practitioner"));
roles.add(new RoleDto("Developer"));
roles.add(new RoleDto("Developer - Professional"));
roles.add(new RoleDto("Business Practitioner - Professional"));
List<RoleDto> sorted = roles.stream().sorted(comparing(r -> r.getName(),
comparing((String s) -> !s.contains("-")))).collect(toList());
for(RoleDto r : sorted)
System.out.println(r.getName());
但是輸出是
Business Practitioner - Expert
Developer - Expert
Developer - Master
Business Practitioner - Master
Developer - Professional
Business Practitioner - Professional
Business Practitioner
Developer
有人可以幫我達到預期的結果嗎
uj5u.com熱心網友回復:
我建議將您的 RoleDto 更改為具有兩個屬性:字串角色和字串級別
現在排序串列的代碼如下所示:
Comparator<RoleDto> compareByRoleAndLevel = Comparator
.comparing(RoleDto::getRole)
.thenComparing(RoleDto::getLevel);
List<RoleDto> sortedRoles = roles.stream()
.sorted(compareByRoleAndLevel)
.collect(Collectors.toList());
uj5u.com熱心網友回復:
您實際上并沒有比較名稱,比較只是檢查名稱是否包含“-”,這就是為什么您在所有不做(以隨機順序)之前得到所有做(以隨機順序)的原因。如果您可以更改 Dto,請參閱@Orr 的答案,否則您可以就地進行名稱拆分/比較,如下所示:
final List<RoleDto> sorted =
roles.stream()
.sorted(
comparing(
RoleDto::getName,
comparing((String s) -> s.split(" - ")[0])
.reversed()
.thenComparing(s -> s.split(" - ").length)
.reversed()
.thenComparing(s -> s.split(" - ")[1])))
.collect(toList());
反轉可能看起來有點不直觀,但實際上每次反轉都會反轉所有先前的比較,因此第一次比較會反轉兩次。要跳過它,您可以改為撰寫:
final List<RoleDto> sorted =
roles.stream()
.sorted(
comparing(
RoleDto::getName,
comparing((String s) -> s.split(" - ")[0])
.thenComparing(s -> -s.split(" - ").length)
.thenComparing(s -> s.split(" - ")[1])))
.collect(toList());
(注意中間比較的減號)
uj5u.com熱心網友回復:
看來您在這里有兩個維度的資料在起作用。
- 業務功能
“業務從業者”和“程式員”。 - 熟練程度
“專家”、“大師”、“專業”,以及隱含的“標準”、“基本”、“新手”等(顯示為無文字)。
嘗試將此類值表示為文本是笨拙的,并且忽略了為此目的而內置于 Java 中的功能。
如果在編譯時所有值都是已知的,則為每個維度創建一個列舉。列舉是一個類,其定義方式為在加載類時自動實體化和命名多個物件。
public enum Function { BUSINESS_PRACTITIONER, PROGRAMMER ; }
public enum Proficiency { EXPERT, MASTER, PROFESSIONAL, NOVICE; }
將它們合并到一個類中。此類的主要目的是透明且不可變地攜帶資料。所以我們可以簡單地定義為一條記錄。
public record Role( Function function , Proficiency proficiency ) { }
我們希望 的實體Role在兩個級別中排序,首先是 by Function,然后是 by Proficiency。所以我們需要Comparable在我們的記錄上實作介面Role。
public record Role( Function function , Proficiency proficiency ) implements Comparable<Role> { … }
每個的排序順序是宣告命名物件的順序。所以我們可以使用一個物件來撰寫必要的compareTo方法。我們使用便捷方法Comparator定義該物件,并為每個物件傳遞一個方法參考。我們使用 將此物件標記為單例,以便頻繁重用。ComparatorcomparingthenComparingstatic
private static Comparator < Role > comparator =
Comparator
.comparing( Role :: function )
.thenComparing( Role :: proficiency );
我們在我們的compareTo方法中使用該比較器。
@Override public int compareTo ( Role other ) { return Role.comparator.compare( this , other ); }
我們像這樣實體化一個角色物件:
Role progPro = new Role( Function.PROGRAMMER , Proficiency.PROFESSIONAL );
如果需要,我們可以制作一組所有可能的角色。
NavigableSet < Role > allPossibleRoles = new TreeSet();
for ( Function function : Function.values() )
{
for ( Proficiency proficiency : Proficiency.values() )
{
allPossibleRoles.add( new Role( function , proficiency ) );
}
}
System.out.println( "allPossibleRoles = " allPossibleRoles );
我們可以看到這些是按照問題規定的順序列出的。
allPossibleRoles = [Role[function=BUSINESS_PRACTITIONER, proficiency=EXPERT], Role[function=BUSINESS_PRACTITIONER, proficiency=MASTER], Role[function=BUSINESS_PRACTITIONER, proficiency=PROFESSIONAL], Role[function=BUSINESS_PRACTITIONER, proficiency=NOVICE], Role[function=PROGRAMMER, proficiency=EXPERT], Role[function=PROGRAMMER, proficiency=MASTER], Role[function=PROGRAMMER, proficiency=PROFESSIONAL], Role[function=PROGRAMMER, proficiency=NOVICE]]
Lastly, we need to emit the text seen in the Question.
Modify the enum classes to take an argument for a display name.
public enum Function
{
BUSINESS_PRACTITIONER( "Business Practitioner" ), PROGRAMMER( "Programmer" );
private final String displayName;
// Constructor
Function ( final String displayName ) { this.displayName = displayName; }
public String getDisplayName ( ) { return displayName; }
}
And the other enum.
public enum Proficiency
{
EXPERT( "Expert" ), MASTER( "Master" ), PROFESSIONAL( "Professional" ), NOVICE( "" );
private final String displayName;
// Constructor
Proficiency ( String displayName ) { this.displayName = displayName; }
public String getDisplayName ( ) { return displayName; }
}
Modify the Role record to generate text in desired format with a getDisplayName method.
import java.util.Comparator;
public record Role( Function function , Proficiency proficiency ) implements Comparable < Role >
{
@Override
public int compareTo ( Role other ) { return Role.comparator.compare( this , other ); }
private static Comparator < Role > comparator =
Comparator
.comparing( Role :: function )
.thenComparing( Role :: proficiency );
public String getDisplayName ( )
{
String x = this.function.getDisplayName();
String y = this.proficiency.getDisplayName().isBlank() ? "" : " - ";
String z = this.proficiency.getDisplayName();
return x y z;
}
}
Example usage.
NavigableSet < Role > allPossibleRoles = new TreeSet(); // NavigableSet/TreeSet keeps elements sorted.
for ( Function function : Function.values() )
{
for ( Proficiency proficiency : Proficiency.values() )
{
allPossibleRoles.add( new Role( function , proficiency ) );
}
}
// Dump to console.
for ( Role role : allPossibleRoles )
{
System.out.println( "role.getDisplayName() = " role.getDisplayName() );
}
role.getDisplayName() = Business Practitioner - Expert
role.getDisplayName() = Business Practitioner - Master
role.getDisplayName() = Business Practitioner - Professional
role.getDisplayName() = Business Practitioner
role.getDisplayName() = Programmer - Expert
role.getDisplayName() = Programmer - Master
role.getDisplayName() = Programmer - Professional
role.getDisplayName() = Programmer
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427531.html
上一篇:Vue3:按降序渲染物件問題
下一篇:比較兩個字典鍵值
