[英]How to convert a list of strings into a list of objects?
我有一個數據庫中的角色列表。 它們的形式
application.Role1.read
application.Role1.write
application.Role2.read
application.Role3.read
所以每個角色都有一個基於讀/寫權限的條目。 我想將角色轉換為 POJO,然后我可以將其作為 JSON 發送到 UI。 每個 POJO 都有角色名稱,以及一個用於讀取或寫入權限的布爾值。
這是 RolePermission 類:
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RolePermission {
private String roleName;
private boolean readAllowed;
private boolean writeAllowed;
public String getRoleName() {
return roleName;
}
public RolePermission setRoleName(String roleName) {
this.roleName = roleName;
return this;
}
public boolean isReadAllowed() {
return readAllowed;
}
public RolePermission setReadAllowed(boolean readAllowed) {
this.readAllowed = readAllowed;
return this;
}
public boolean isWriteAllowed() {
return writeAllowed;
}
public RolePermission setWriteAllowed(boolean writeAllowed) {
this.writeAllowed = writeAllowed;
return this;
}
}
我正在做這樣的轉換:
public static final String ROLE_PREFIX = "application.";
public static final String ROLE_READ_PERMISSION = "read";
public static final String ROLE_WRITE_PERMISSION = "write";
@Override
public List<RolePermission> getRoles(Backend backend) {
List<String> allRoles = backend.getRoles()
.stream()
.map(s -> s.replace(ROLE_PREFIX, ""))
.sorted()
.collect(Collectors.toList());
Map<String, RolePermission> roleMap = new HashMap<>();
for (String role : allRoles) {
String[] tokens = role.split(".");
String roleName = tokens[0];
String permission = tokens[1];
if (!roleMap.containsKey(roleName))
roleMap.put(roleName, new RolePermission().setRoleName(roleName));
RolePermission permission = roleMap.get(roleName);
if (ROLE_READ_PERMISSION.equals(permission))
permission.setReadAllowed(true);
if (ROLE_WRITE_PERMISSION.equals(permission))
permission.setWriteAllowed(true);
}
return new LinkedList<>(roleMap.values());
}
有沒有辦法使用 Java 8 流執行上面的 foreach 循環?
這是一個只返回角色列表的模擬后端實例:
public class Backend {
public List<String> getRoles() {
return Arrays.asList(
"application.Role1.read",
"application.Role1.write",
"application.Role2.read",
"application.Role3.read"
);
}
}
您可以使用groupingBy
將同一個 roleName 的不同權限連接在一起。
public static final String ROLE_PREFIX = "application.";
public static final String ROLE_READ_PERMISSION = "read";
public static final String ROLE_WRITE_PERMISSION = "write";
@Override
public List<RolePermission> getRoles(Backend backend) {
Map<String, List<String[]>> allRoles = backend.getRoles()
.stream()
.map(s -> s.replace(ROLE_PREFIX, "")) // something like "Role1.read"
.map(s -> s.split("\\.")) // something like ["Role1", "read"]
.collect(Collectors.groupingBy(split -> split[0]));
return allRoles.values()
.stream()
.map(this::buildPermission)
.collect(Collectors.toList());
}
private RolePermission buildPermission(List<String[]> roleEntries) {
RolePermission permission = new RolePermission().setRoleName(roleEntries.get(0)[0]);
roleEntries.stream()
.forEach(entry -> {
if (ROLE_READ_PERMISSION.equals(entry[1]))
permission.setReadAllowed(true);
if (ROLE_WRITE_PERMISSION.equals(entry[1]))
permission.setWriteAllowed(true);
});
return permission;
}
我還認為您的String.split
在原始帖子中使用了不正確的正則表達式,因為.
是一個特殊的正則表達式字符。 我已經測試過這個並且它工作正常。
輸出:
[RolePermission(roleName=Role3, readAllowed=true, writeAllowed=false),
RolePermission(roleName=Role2, readAllowed=true, writeAllowed=false),
RolePermission(roleName=Role1, readAllowed=true, writeAllowed=true)]
您的for
循環可以替換為現有流中第二次調用map
和toMap
收集器:
public List<RolePermission> getRoles(Backend backend)
{
Map<String, RolePermission> allRoles = backend.getRoles()
.stream()
.map(s -> s.replace(ROLE_PREFIX, ""))
.sorted()
.map(this::mapStringToRolePermission)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, RolePermission::merge));
return new ArrayList<>(allRoles.values());
}
其中mapStringToRolePermission
:
private static Map.Entry<String, RolePermission> mapStringToRolePermission(String role)
{
String roleName = role.substring(0, role.indexOf('.'));
RolePermission rolePermission = new RolePermission();
rolePermission.setRoleName(roleName);
rolePermission.setReadAllowed(role.endsWith(ROLE_READ_PERMISSION));
rolePermission.setWriteAllowed(role.endsWith(ROLE_WRITE_PERMISSION));
return new AbstractMap.SimpleEntry<>(roleName, rolePermission);
}
和RolePermission
的附加方法merge
:
public RolePermission merge(RolePermission another)
{
if (another.isReadAllowed())
setReadAllowed(true);
if (another.isWriteAllowed())
setWriteAllowed(true);
return this;
}
Java 流有一個 map 函數,因此您可以使用它來將 String 映射到 RolePermission(或您想要的任何對象),然后將結果收集到一個列表中。 這樣的事情對你有用嗎? 看起來您或多或少已經完成了 String 到 RolePermission 的轉換
final List<RolePermission> roles = getRoles().stream().map(roleString -> { <your conversion code> }).collect(Collectors.toList());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.