简体   繁体   中英

Java - Looping over complex collection of Objects

I have a general question about looping over a collection containing a complex object.

  • I have a Collection<Object> , which contains an Array<E> of LinkedHashMap<K,V> that I'm trying to extract values from.
  • I have tried various loops to get to the Key, Value pair but with no luck, something like;

The object looks like;

复杂对象

Collection<Object> dsidsToExclude = Arrays.asList(param.get("idsToExclude"));
    for(Object id : dsidsToExclude) {
            if(id instanceof ArrayList) {
            // Loop over the list of <K,V>
            for(Object kv : id) {
               // I want to get extract the kv pairs here..
              }
            }
        }

I want to know what the best way of doing this efficiently, any suggestions? Thanks.

As long as the contents of the input collection may be specified as Collection<List<Map<K, V>>> (note use of interfaces List and Map instead of implementations ArrayList and LinkedHashMap ), it would be more appropriate to implement a generic method typed with K, V to get rid of instanceof and explicit casting:

public static <K, V> doSomething(Collection<List<Map<K, V>>> input) {
    for (List<Map<K, V>> list : input) {
        for (Map<K, V> map : list) {
            for (Map.Entry<K, V> entry : map.entrySet()) {
                // do what is needed with entry.getKey() , entry.getValue()
            }
        }
    }
}

Similarly, methods forEach may be used for the collection, list, and map:

public static <K, V> doSomethingForEach(Collection<List<Map<K, V>>> input) {
    input.forEach(list ->
        list.forEach(map ->
            map.forEach((k, v) -> // do what is needed with key k and value v
                System.out.printf("key: %s -> value: %s%n", k, v);
            );
        )
    );
}

Also, it is possible to use Stream API, particularly flatMap to access contents of all innermost maps. Optionally, null values may be filtered as shown below

public static <K, V> doSomethingStream(Collection<List<Map<K, V>>> input) {
    input.stream()                 // Stream<List<Map<K, V>>>
         .filter(Objects::nonNull) // discard null entries in collection
         .flatMap(List::stream)    // Stream<Map<K, V>>
         .filter(Objects::nonNull) // discard null entries in list
         .flatMap(map -> map.entrySet().stream()) // Stream<Map.Entry<K, V>>
         .forEach(e -> System.out.printf(
             "key: %s -> value: %s%n", e.getKey(), e.getValue()
         ));
}

Arrays.asList(something) will generate list with one element. You do not need to do it.

Object object = param.get("idsToExclude");

You can check object and cast to list.

if (object instanceof List) {
  List list = (List) object;
}

Every item in the list needs to be checked and cast.

for (Object item : list) {
  if (item instanceof Map) {
    Map map = (Map) item;
  }
}

You can get key and value from map item.

Object key = map.getKey();
Object value = map.getValue();

Full example:

Object object = param.get("idsToExclude");
if (object instanceof List) {
  List list = (List) object;
  for (Object item : list) {
    if (item instanceof Map) {
      Map map = (Map) item;
      Object key = map.getKey();
      Object value = map.getValue();
      // You can cast key and value to other object if you need it
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM