简体   繁体   中英

how to store the values that has the same parent key

lets say I have:

bob:V
bob:A
bob:B
bob:C
bob:C
sally:B
sally:C
sally:A
steve:A
steve:B
steve:C

how do I store:

the values as:

bob={V,A,B,C,C}, sally={B,C,A}, steve={A,B,C}

and for any guy who has a sequence A,B,C repeated how do I get that person name?

I am fairly new to Java and Im trying to implement this scenario, as I dont see anything like this in this communtiy.

First, I would store the attributes in a Map<String,String> . This will make it easier to filter the attributes later. I am using a record in lieu of a class but a class would work as well.

record Person(String getName, String getAttribute) {
}

Create the list of Person objects

List<Person> list = List.of(new Person("bob", "V"),
        new Person("bob", "A"), new Person("bob", "B"),
        new Person("bob", "C"), new Person("bob", "C"),
        new Person("sally", "B"), new Person("sally", "C"),
        new Person("sally", "A"), new Person("steve", "A"),
        new Person("steve", "B"), new Person("steve", "C"));

Now create the map. Simply stream the list of people and concatenate the attributes for each person.

Map<String, String> personMap = list.stream()
        .collect(Collectors.toMap(Person::getName,
                Person::getAttribute, String::concat));

The map will look like this.

bob=VABCC
steve=ABC
sally=BCA

Now grab the name based on an attribute string.

Now stream the entries of the map and pass the entry whose value contains the attribute string. Then retrieve the key (name) and return as a list of names.


String attributes = "ABC";
ListString> results = personMap.entrySet().stream()
        .filter(e -> e.getValue().contains(attributes))
        .map(Entry::getKey).collect(Collectors.toList());

System.out.println(results);

prints

[bob, steve]

Alternative approach using Map<String, List<String>>

Group the objects by name but the values will be a list of attributes instead of a string.

Map<String, List<String>> personMap = list.stream()
        .collect(Collectors.groupingBy(Person::getName,
                Collectors.mapping(Person::getAttribute,
                        Collectors.toList())));

The map will look like this.

bob=[V, A, B, C, C]
steve=[A, B, C]
sally=[B, C, A]

To facilitate testing the attributes, a BiPredicate is used to stream the list and concatinate the attributes and then check and see if it contains the attribute string.

BiPredicate<Entry<String, List<String>>, String> contains =
        (entry, attr) -> entry.getValue().stream()
                .collect(Collectors.joining()).contains(attr);

As before, stream the entry set of the map and apply the filter to pass those entries which satisfy the condition. In this case, the filter invokes the BiPredicate .

String attributes = "ABC";
List<String> results = personMap.entrySet().stream()
        .filter(e->contains.test(e, attributes))
        .map(Entry::getKey).collect(Collectors.toList());

System.out.println(results);

prints

[bob, steve]
 

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