#android #arraylist #android-recyclerview
#Android #arraylist #android-recyclerview
Вопрос:
У меня есть массив JSON, который необходимо проанализировать таким образом, чтобы он был похож на прилагаемый скриншот. Так, например, массив JSON будет приведен ниже, и он содержит шесть элементов, которые необходимо проанализировать с помощью цикла, но не может создать правильную структуру данных. Существуют разные уровни, и если у дочерних элементов есть общий родительский элемент, ему необходимо управлять только этим родительским идентификатором. Для уровня 1 не будет родительского идентификатора
Массив JSON
"clubSubAreas":[
{
"id":573801,
"clubId":16733,
"areaId":58482,
"name":"subcoach c2a",
"level":4,
"parentId":569125,
"clubMemberSubAreas":{}
},
{
"id":569114,
"clubId":16733,
"areaId":53279,
"name":"Hockey",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
},
{
"id":569122,
"clubId":16733,
"areaId":53280,
"name":"Team H2",
"level":2,
"parentId":569114,
"clubMemberSubAreas":{}
},
{
"id":569131,
"clubId":16733,
"areaId":53281,
"name":"Coach H2",
"level":3,
"parentId":569122,
"clubMemberSubAreas":{}
},
{
"id":569119,
"clubId":16733,
"areaId":53280,
"name":"Team F2",
"level":2,
"parentId":569112,
"clubMemberSubAreas":{}
},
{
"id":569127,
"clubId":16733,
"areaId":53281,
"name":"Coach F1",
"level":3,
"parentId":569118,
"clubMemberSubAreas":{}
},
{
"id":569851,
"clubId":16733,
"areaId":58482,
"name":"sub coach f1",
"level":4,
"parentId":569127,
"clubMemberSubAreas":{}
},
{
"id":569112,
"clubId":16733,
"areaId":53279,
"name":"Football",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
},
{
"id":569118,
"clubId":16733,
"areaId":53280,
"name":"Team F1",
"level":2,
"parentId":569112,
"clubMemberSubAreas":{}
},
{
"id":569716,
"clubId":16733,
"areaId":58482,
"name":"subcoasch c2",
"level":4,
"parentId":569125,
"clubMemberSubAreas":{}
},
{
"id":569125,
"clubId":16733,
"areaId":53281,
"name":"Coach C2",
"level":3,
"parentId":569116,
"clubMemberSubAreas":{}
},
{
"id":569116,
"clubId":16733,
"areaId":53280,
"name":"Team C2",
"level":2,
"parentId":569113,
"clubMemberSubAreas":{}
},
{
"id":573787,
"clubId":16733,
"areaId":58482,
"name":"subcoach c2 new",
"level":4,
"parentId":573786,
"clubMemberSubAreas":{}
},
{
"id":573786,
"clubId":16733,
"areaId":53281,
"name":"Coach C2 new",
"level":3,
"parentId":569116,
"clubMemberSubAreas":{}
},
{
"id":569113,
"clubId":16733,
"areaId":53279,
"name":"Cricket",
"level":1,
"parentId":null,
"clubMemberSubAreas":{}
}
]
По сути, я хочу показать данные в представлении recycler, но не могу создать структуру данных с помощью ArrayList / Hashmap / TreeMap из заданного ответа JSON
Моя работа:
ArrayList<ClubSubArea> clubSubAreaDept = new ArrayList<>();
ArrayList<ClubSubArea> clubSubAreaSubDept = new ArrayList<>();
ArrayList<ClubSubArea> clubSubAreaFunc = new ArrayList<>();
ArrayList<ClubSubArea> clubSubAreaLevelFour = new ArrayList<>();
for (ClubSubArea clubSubArea : clubMemberDataEdit.getClubSubAreas()) {
if (clubSubArea.getLevel() == 1) {
clubSubAreaDept.add(clubSubArea);
} else if (clubSubArea.getLevel() == 2) {
clubSubAreaSubDept.add(clubSubArea);
} else if (clubSubArea.getLevel() == 3) {
clubSubAreaFunc.add(clubSubArea);
} else {
clubSubAreaLevelFour.add(clubSubArea);
}
}
ArrayList<ClubAreaCombine> clubAreaCombines1 = new ArrayList<>();
ArrayList<ClubAreaCombine> clubAreaCombines = new ArrayList<>();
if (clubAreas != null amp;amp; clubAreas.size() > 0) {
for (ClubSubArea clubSubAreaDepartment : clubSubAreaDept) {
for (ClubSubArea clubSubAreaSubDepartment : clubSubAreaSubDept) {
if (clubSubAreaSubDepartment.getParentId() == clubSubAreaDepartment.getId()) {
for (ClubSubArea clubSubAreaFunction : clubSubAreaFunc) {
if (clubSubAreaFunction.getParentId() == clubSubAreaSubDepartment.getId()) {
if (clubSubAreaLevelFour != null amp;amp; clubSubAreaLevelFour.size() > 0) {
for (ClubSubArea clubSubAreaLFour : clubSubAreaLevelFour) {
if (clubSubAreaLFour.getParentId() == clubSubAreaFunction.getId()) {
ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
clubSubAreaSubDepartment,
clubSubAreaFunction,
clubSubAreaLFour);
clubAreaCombines1.add(clubAreaCombine);
} else {
ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
clubSubAreaSubDepartment,
clubSubAreaFunction, null);
clubAreaCombines1.add(clubAreaCombine);
}
}
} else {
ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
clubSubAreaSubDepartment,
clubSubAreaFunction,
null);
clubAreaCombines1.add(clubAreaCombine);
}
} else {
ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
clubSubAreaSubDepartment,
null,
null);
clubAreaCombines1.add(clubAreaCombine);
}
}
} else {
ClubAreaCombine clubAreaCombine = new ClubAreaCombine(clubSubAreaDepartment,
null,
null,
null);
clubAreaCombines1.add(clubAreaCombine);
}
}
}
}
for (ClubAreaCombine clubAreaCombine : clubAreaCombines1) {
if (!clubAreaCombines.contains(clubAreaCombine)) {
clubAreaCombines.add(clubAreaCombine);
}
}
ClubSubArea
public class ClubSubArea implements Serializable {
@SerializedName("id")
private long id;
@SerializedName("clubId")
private Long clubId;
@SerializedName("name")
private String name;
@SerializedName("level")
private int level;
@SerializedName("areaId")
private Long areaId;
@SerializedName("parentId")
private Long parentId;
@SerializedName("_links")
List<Links> links;
List<ClubSubArea> subAreaList = new ArrayList<>();
@SerializedName("clubMemberSubAreas")
ClubMemberSubAreas clubMemberSubAreas;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Long getClubId() {
return clubId;
}
public void setClubId(Long clubId) {
this.clubId = clubId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public Long getAreaId() {
return areaId;
}
public void setAreaId(Long areaId) {
this.areaId = areaId;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public List<Links> getLinks() {
return links;
}
public void setLinks(List<Links> links) {
this.links = links;
}
public List<ClubSubArea> getSubAreaList() {
return subAreaList;
}
public void setSubAreaList(ArrayList<ClubSubArea> subAreaList) {
this.subAreaList = subAreaList;
}
public ClubMemberSubAreas getClubMemberSubAreas() {
return clubMemberSubAreas;
}
public void setClubMemberSubAreas(ClubMemberSubAreas clubMemberSubAreas) {
this.clubMemberSubAreas = clubMemberSubAreas;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClubSubArea that = (ClubSubArea) o;
if (id != that.id) return false;
if (level != that.level) return false;
if (!clubId.equals(that.clubId)) return false;
return parentId != null ? parentId.equals(that.parentId) : that.parentId == null;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result clubId.hashCode();
result = 31 * result level;
result = 31 * result (parentId != null ? parentId.hashCode() : 0);
return resu<
}
}
Данные, отображаемые в Интернете следующим образом
Комментарии:
1. Покажите свою работу, пожалуйста.
2. @IntelliJAmiya добавил мою работу
Ответ №1:
Попробуйте следующее. Я не тестировал его, поэтому, возможно, есть некоторые ошибки. (Я изменил ваш ClubSubArea, чтобы все поля были общедоступными, чтобы не нужно было использовать геттеры / сеттеры)
class CrazyMapper {
List<RowItem> map(List<ClubSubArea> items) {
// We return an empty list if there is no items.
if (items.size() == 0) {
return new ArrayList<>();
}
// We create a list with all the last elements (the ones not used as parent)
List<ClubSubArea> children = new ArrayList<>();
for (ClubSubArea club : items) {
if (isChild(club, items)) {
children.add(club);
}
}
// Then we remove all the children ClubSubArea from the items list
items.removeAll(children);
// Now we want to build each row.
// Each row is a list of ClubSubArea. In your example, one will be Cricket, then Team, then Captain...
// We want them in that order. According to your Json, the Coach is the one with the level max,
// then the Captain, then the Team, then Cricket.
// Cricket has no parent but otherwise, Coach has Captain id as a parent, and Captain has
// Teams id as a parent.
// With buildRowList we gonna create the list in that order (Cricket, Team,...) using the parent id.
List<RowItem> rowItems = new ArrayList<>();
for (ClubSubArea club : children) {
List<ClubSubArea> result = new ArrayList<>();
result.add(club);
buildRowList(items, club, result);
rowItems.add(new RowItem(result));
}
return rowItems;
}
// Check if the item is used as parent in another one in the list. If not, it's the last
// element (child).
private boolean isChild(ClubSubArea item, List<ClubSubArea> items) {
for (ClubSubArea club : items) {
if (club.parentId == item.id) {
return false;
}
}
return true;
}
// This method is recursive (it calls itself until it can't (parent id is null)).
private void buildRowList(List<ClubSubArea> list, ClubSubArea current, List<ClubSubArea> result) {
for (ClubSubArea club : list) {
if (club.id == current.parentId) {
// We add the parent at index 0 in order to have the list starting with the highest
// parent (parent with no parent id (should be the one with level 1))
result.add(0, club);
if (club.parentId != null) {
// We try to find the parent's parent.
buildRowList(list, club, result);
}
// We don't want to continue to loop if we found the parent
return;
}
}
}
}
// This is the class used by the adapter. The adapter will handle a list of RowItem.
class RowItem {
public RowItem(List<ClubSubArea> items) {
this.items = items;
}
List<ClubSubArea> items;
}
Комментарии:
1. Он отлично работает, если уровней четыре, но в сценарии, когда уровней меньше четырех, для этого не создается строка. Например, у меня есть данные до трех уровней, таких как футбол, команда F1 и капитан F1, тогда для этого не создается строка
2. Смешаны ли данные с максимальным значением 3 и данные с максимальным значением 4?
3. Да, это может зависеть от пользователя, для скольких уровней он хочет добавить данные. Предположим, что он добавил Cricket, тогда максимальный уровень будет равен 1, а если он добавит Cricket, Team1, тогда максимальный уровень будет равен 2, и так далее…
4. @Salmankhan Я обновил вышесказанное. Теперь
RowItem
будет содержать список разного размера в зависимости от того, что выбрал пользователь5. Чертовски логичный человек. Большое вам спасибо, теперь он работает отлично. Еще раз большое спасибо.