FreeOnGoo:
私は、複雑なエンティティの構造を有しています。これは前の項目(「previodElementId」)のIDが含まれています
interface IPreviousElementEntity<PK> {
public void setId(PK id);
public PK getId();
public void setPreviousElementId(PK previousElementId);
public PK getPreviousElementId();
}
DBからすべてのエンティティを受け取った後、私はリンクリストに結果のリストを変換する必要があり、リンクされたリストは、以前のIDによって組織されなければなりません。
私は、変換のために、次のコードを書きました:
static <T extends IPreviousElementEntity> LinkedList<T> getLinkedListByPreviousId(Collection<T> collection) {
LinkedList<T> linkedList = new LinkedList<>();
if (collection == null || collection.isEmpty())
return linkedList;
// first find root element
collection.stream()
.filter(element -> element.getPreviousElementId() == null)
.forEach(linkedList::add);
if (linkedList.isEmpty()) return linkedList;
// TODO: convert to use stream. Please help!
Boolean isRun = true;
while (isRun) {
for (T element : collection) {
isRun = false;
if (linkedList.getLast().getId().equals(element.getPreviousElementId())) {
linkedList.add(element);
isRun = true;
break;
}
}
}
return linkedList;
}
しかし、このコードはひどいです!それはストリーム上のすべてのこれらの変換を記述することは可能ですか?私は特にループしながら、雷鳴を取り除きたいです。
私の完全なコード:
import java.util.*;
public class App {
public static void main(String[] args) {
Entity entity1 = new Entity(3L, 2L, "third");
Entity entity2 = new Entity(2L, 1L, "second");
Entity entity3 = new Entity(4L, 3L, "forth");
Entity entity4 = new Entity(1L, null, "first");
List<Entity> entities = new ArrayList<>();
entities.add(entity1);
entities.add(entity2);
entities.add(entity3);
entities.add(entity4);
LinkedList<Entity> linkedListByPreviousId = getLinkedListByPreviousId(entities);
System.out.println(linkedListByPreviousId);
}
private static <T extends IPreviousElementEntity> LinkedList<T> getLinkedListByPreviousId(Collection<T> collection) {
LinkedList<T> linkedList = new LinkedList<>();
if (collection == null || collection.isEmpty())
return linkedList;
// first find root element
collection.stream()
.filter(element -> element.getPreviousElementId() == null)
.forEach(linkedList::add);
if (linkedList.isEmpty()) return linkedList;
//TODO: convert to use stream. Please help!
Boolean isRun = true;
while (isRun) {
for (T element : collection) {
isRun = false;
if (linkedList.getLast().getId().equals(element.getPreviousElementId())) {
linkedList.add(element);
isRun = true;
break;
}
}
}
return linkedList;
}
}
interface IPreviousElementEntity<PK> {
public void setId(PK id);
public PK getId();
public void setPreviousElementId(PK previousElementId);
public PK getPreviousElementId();
}
class Entity implements IPreviousElementEntity<Long> {
private Long id;
private Long previousElementId;
private String name;
public Entity(Long id, Long previousElementId, String name) {
this.id = id;
this.previousElementId = previousElementId;
this.name = name;
}
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@Override
public Long getPreviousElementId() {
return previousElementId;
}
@Override
public void setPreviousElementId(Long previousElementId) {
this.previousElementId = previousElementId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Entity entity = (Entity) o;
return Objects.equals(id, entity.id) &&
Objects.equals(previousElementId, entity.previousElementId) &&
Objects.equals(name, entity.name);
}
@Override
public int hashCode() {
return Objects.hash(id, previousElementId, name);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Entity{");
sb.append("id=").append(id);
sb.append(", previousElementId=").append(previousElementId);
sb.append(", name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
方位磁針 :
それはリストを使用して、そして何より多くのオプションが存在しなくなるまで継続的に繰り返すはO(n ^ 2)の操作を行うしようとするため、一方のループは厄介です。
O(N)操作キーとしてpreviousElementIdを使用してマップを使用することにより、より適切です。
if (linkedList.isEmpty()) return linkedList;
//create a map with previousElementId as Key, T as Object
Map<Integer, T> map = collection.stream().collect(
Collectors.toMap(T::getPreviousElementId, Function.identity()));
//we fetch nodes using the current ID as the key
T node = map.get(linkedList.getLast().getId());
while(node != null) {
linkedList.add(node);
node = map.get(node.getId());
}