Java - извлечение индивидуальных значений из списка на карте - PullRequest
1 голос
/ 31 марта 2019

У меня есть TreeMap с 3 записями, все из отдельных списков ArrayLists.

Я использую следующий код:

Map<String, List<String>> mapOne = new TreeMap<String, List<String>>();
List<String> listFour = Arrays.asList("");

ArrayList<String> listOne = new ArrayList<>();
listOne.add("Writer");
listOne.add("Actor");
listOne.add("Politician");
listOne.add("Dancer");

ArrayList<String> listTwo = new ArrayList<>();
listTwo.add("James");
listTwo.add("Robert");
listTwo.add("Tereza");
listTwo.add("John");

ArrayList<String> listThree = new ArrayList<>();
listThree.add("Joyce");
listThree.add("Redford");
listThree.add("May");
listThree.add("Travolta");

for (int i = 0; i < listOne.size(); i++) {

    String stringOne = listOne.get(i);
    String stringTwo = listTwo.get(i);
    String stringThree = listThree.get(i);

    listFour = Arrays.asList(stringTwo, stringThree);

    mapOne.put(stringOne, listFour);

}

Теперь я хочу получить отдельные значения String из отсортированного списка. вот так:

for (Map.Entry<String, List<String>> entry : mapOne.entrySet()) {

    String key = entry.getKey();

    for (String value : entry.getValue()) {

        System.out.println(value);

    }
}

Приведенный выше код печатает список как

{Robert Redford , John Travolta , Tereza May , James Joyce} 

Можно ли выполнить итерацию по списку таким образом, чтобы получить отдельные списки, один с именами, а другой с фамилиями?

listOne = {Robert , John , Tereza, James}
listTwo = {Redford, Travolta, May, Joyce}

Или я должен использовать совершенно другой подход?

Все началось с необходимости сортировки одного ArrayList и другого соответственно. То, что вначале казалось тривиальным, оказалось настоящим испытанием.

Я вроде программиста-хобби, поэтому профессионалы любезно относятся ко мне.

Ответы [ 2 ]

2 голосов
/ 31 марта 2019

Кажется, вы чрезмерно инженерны как-то.

Сначала я отвечу Stream решением, просто для того, чтобы попробовать.
Обратите внимание, что я лично предпочел бы «старый» итеративный подход (см. Ниже).

// You can see by the use of AtomicInteger that this isn't the right road to take!
final AtomicInteger i = new AtomicInteger();
final Collection<List<String>> values1 =
        mapOne.values()
              .stream()
              .flatMap(v -> v.stream())
              .collect(partitioningBy(o -> i.getAndIncrement() % 2 != 0))
              .values();

Выход: [[Robert, John, Tereza, James], [Redford, Travolta, May, Joyce]]


Итеративный подход

final Collection<String> names = new ArrayList<>();
final Collection<String> surnames = new ArrayList<>();

for (final List<String> value : mapOne.values()) {
    names.add(value.get(0));
    surnames.add(value.get(1));
}

Выход:

[Robert, John, Tereza, James]
[Redford, Travolta, May, Joyce]

Это безопасно, потому что вы знаете, что каждый внутренний List имеет два элемента.


То, что Дж.Б. Низет говорит вам сделать (спасибо ему за то, что он написал это), в основном, заключается в создании соответствующего class

public class Person {
   private String profession;
   private String name;
   private String surname;

   // Getters and setters. JavaBean style
}

И приступить к сортировке Collection<Person>.
Например, как можно проще

final List<Person> persons = new ArrayList<>();

// Populate list

Collections.sort(persons, (p1, p2) -> {
    // Not null-safe
    return p1.getName().compareTo(p2.getName());
});

Это отсортирует список по name. Он не вернет новый список, а просто изменит входной.

0 голосов
/ 04 апреля 2019

Объединение всех ценных советов, онлайн-поисков и моих усилий - это мое окончательное решение (в надежде, что оно будет полезно для других).Мне кажется, мое решение является минимальным и простым:

    List<Sites> listOfSites = new ArrayList<Sites>();

    for (int i = 0; i < classLists.listSites.size(); i++) {

        String site = classLists.listSites.get(i);   
        String description = classLists.listSitesDesc.get(i);
        String link = classLists.listSitesLinks.get(i);

        listOfSites.add(new Sites(site, description, link));

    }

    Collections.sort(listOfSites, (p1, p2) -> {

        return p1.getName().compareTo(p2.getName());

    });

    final ArrayList<String> titles = new ArrayList<>();
    final ArrayList<String> descriptions = new ArrayList<>();
    final ArrayList<String> links = new ArrayList<>();

    for (Sites s : listOfSites) {

        String name = s.getName();
        String description = s.getDesc();
        String link = s.getLink();

        titles.add(name);
        descriptions.add(description);
        links.add(link);

    }

Ниже класса Сайты:

public class Sites implements Comparable<Sites> {
    private String name;
    private String description;
    private String link;

    public Sites(String name, String description, String link) {

        this.name  = name;
        this.description = description;
        this.link = link;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {

        this.name = name;

    }

    public String getDesc() {

        return description;
    }

    public void setDesc(String description) {

        this.description = description;

    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {

        this.link = link;

    }

} 
...