1

I am new to Java and I have a Object Array got from API shown as below.

Actually, each Object in a list is a Map.

I would like to remove one of the keys in each Map.

Below is what I tried, but I cannot solve the issue:

remove() is not defined for object 

What is the appropriate way to do that?

Object Array:
List<Object> fruit: [{apple=3, orange=4}, {apple=13, orange=2}, {apple=1, orange=8}]

Code I tried:
List<Object> newList = fruit.stream().filter(x->x.getKey().equals("orange")).collect(Collectors.toList());

And

List<Object> newList = fruit.forEach(x->{
                                     x.remove();
                                     }););

Remark:
API Resp: [{country=US, fields={apple=3, orange=4},{country=CAD, fields={apple=1, orange=4}]
List<Object> fruit= apiResult.stream()
                             .map(x->x.get("fields"))            
                             .collect(Collectors.toList());
3
  • @AlexanderIvanchenko Sorry, I am new to Java and still exploring it. I have put the API resp message in "Remark". In this case, what is the proper way to cast the type? I want to convert the API message into a list of fruit. Thanks! Commented May 26, 2022 at 11:02
  • proper way to cast the type - In Java, a good practice is to avoid type casting. Your list should be of type List<Map<Integer, Integer> in the first place. By using Object as a generic type and performing type-casts, you're relinquishing the built-in type-safety mechanism, i.e. the compiler will not help you with verifying the code. And it makes it difficult to read. Commented May 26, 2022 at 11:17
  • In your code, you're trying to create a copy, so you want to keep the previous version where all entries are intact and modify a copy? Commented May 26, 2022 at 12:20

2 Answers 2

2

This will remove the oranges from the maps:

fruit.forEach(x -> ((Map<?,?>) x).remove("orange"));

(It is more complicated you wanted to create a new list containing new maps with the oranges removed. But that is not what your attempts seemed to be doing.)

One thing you were missing in all of your attempts is that you need to cast the list elements to Map.

But a cleaner solution would be to define List<Object> fruit as List<Map<String, Integer>> fruit.


In the question title you asked:

How to cast Object Array to Map Array and remove key in the Map?

The short answer is that you can't. An array object that has been created as an Object[] cannot be cast to Map<?, ?>[]. But as you can see, you don't need to do that to solve your problem.

Sign up to request clarification or add additional context in comments.

Comments

0

How to cast Object Array to Map Array

It seems like you're confusing an array and ArrayList.

An array is a data-container that occupies a contiguous block of memory and has a fixed length.

ArrayList is a built-in implementation of the Dynamic array data structure, which is backed by an array, but contrary to a plain array it's capable to grow is size and provides a lot of useful behavior.

If your background is JavaScript, then ArrayList is closer to arrays in JavaScript.

Regarding casting, as I've said, you shouldn't use the Object in the first place. Your list should be of type List<Map<String, Integer>> then there would be no problem.

If we would try to convert this list objects into its actual type - no luck:

List<Map<String, Integer>> fruitConverted = (List<Map<String, Integer>>) fruit; // that would not compile, the compiler will not allow that

That work around it to fool the compiler by using an intermediate variable of so-called row type.

List rowList = fruit; 
        
List<Map<String, Integer>> fruitConverted = rowList;

In this case the compiler will issue a warning, but the code will compile. But you should be aware that a vary bad stale of coding.

For more information on type conversion see.

I would like to remove one of the key in each dictionary

In your code, you're trying to create a new list in different ways, so it seems like you want to keep the previous version of the list with all maps intact.

If so you can use streams to create a duplicate of every entry (excluding entries with an undesired key "orange") for each map and then collect then into a list.

public static void main(String[] args) {
    List<Object> fruit =
        List.of(Map.of("apple", 3, "orange", 4),
                Map.of("apple", 13, "orange", 2),
                Map.of("apple", 1, "orange", 8));

    List<Map<String, Integer>> newList = fruit.stream()
        .map(map -> ((Map<String, Integer>) map).entrySet().stream()
            .filter(entry -> !entry.getKey().equals("orange")) // will retain entries with key that not equal to "orange"
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
        .collect(Collectors.toList());

    System.out.println(newList);
}

Output:

[{apple=3}, {apple=13}, {apple=1}]

But if you don't need the previous version of the list, then you can use a combination of forEach() an remove().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.