ජාවා 8 ලැයිස්තුව <V> සිතියමට <K, V>


944

ජාවා 8 හි ධාරාවන් සහ ලැම්බඩාස් භාවිතා කරමින් සිතියමකට වස්තු ලැයිස්තුවක් පරිවර්තනය කිරීමට මට අවශ්‍යය.

ජාවා 7 සහ ඊට පහළින් මම එය ලියන්නේ එලෙසයි.

private Map<String, Choice> nameMap(List<Choice> choices) {
        final Map<String, Choice> hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

ජාවා 8 සහ ගුවා භාවිතයෙන් මට මෙය පහසුවෙන් ඉටු කර ගත හැකි නමුත් ගුවා නොමැතිව මෙය කරන්නේ කෙසේදැයි දැන ගැනීමට මම කැමතියි.

ගුවා හි:

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, new Function<Choice, String>() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

සහ ජාවා 8 ලැම්බඩාස් සමඟ ගුවා.

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, Choice::getName);
}

Answers:


1410

Collectorsප්‍රලේඛනය මත පදනම්ව එය එතරම් සරල ය:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName,
                                              Function.identity()));

169
පැති සටහනක් ලෙස, ජාවා 8 න් පසුව වුවද, ජේඩීකේට තවමත් සංක්ෂිප්ත තරඟයකට තරඟ කළ නොහැක. ගුවා විකල්පය කියවිය හැකි තරම් පෙනේ : Maps.uniqueIndex(choices, Choice::getName).
බොග්ඩන් කැල්මාක්

4
(Statically ආනයනය) භාවිතා කරමින් Seqසිට JOOL පුස්තකාල (මම ජාවා 8 භාවිතා කරන ඕනෑම කෙනෙකුට නිර්දේශ කරනවා වන), ඔබ ද සමග brevity දියුණු කර ගත හැකිය: seq(choices).toMap(Choice::getName)
lukens

5
Function.identity භාවිතා කිරීමෙන් යම් ප්‍රතිලාභ තිබේද? මම කිව්වේ, එය -> එය කෙටි
ෂබන්ක්

10
abshabunc මම කිසිම ප්‍රතිලාභයක් නොදන්නා අතර ඇත්ත වශයෙන්ම it -> itමා භාවිතා කරමි. Function.identity()මෙහි වැඩි වශයෙන් භාවිතා කරනුයේ එය යොමු කරන ලද ලියකියවිලි වල භාවිතා කර ඇති නිසා සහ ලිවීමේදී
ලැම්බඩාස්

12
apzapl, ඔහ්, ඇත්ත වශයෙන්ම මෙය පිටුපස හේතු ඇති බව පෙනේ
stackoverflow.com/questions/28032827/…

309

ලැයිස්තුවේ ඇති සියලුම අංග සඳහා ඔබේ යතුර අද්විතීය යැයි සහතික නොවන්නේ නම් , ඔබ එය a Map<String, List<Choice>>වෙනුවට ආදේශ කළ යුතුයMap<String, Choice>

Map<String, List<Choice>> result =
 choices.stream().collect(Collectors.groupingBy(Choice::getName));

76
මෙය සැබවින්ම ඔබට සිතියම <string, list <Choice>> ලබා දෙයි, එය අද්විතීය නොවන යතුරු සඳහා ඇති හැකියාව සමඟ කටයුතු කරයි, නමුත් OP ඉල්ලා සිටි දේ නොවේ. ගුවා හි, Multimaps.index (තේරීම්, තේරීම :: getName) ඔබට කෙසේ හෝ අවශ්‍ය නම් මෙය වඩා හොඳ විකල්පයකි.
රිචඩ් නිකල්ස්

හෝ ඒ වෙනුවට ගුවා හි බහුමාප <string, Choice> භාවිතා කරන්න. සිතියමක් <
නීරාජ් බී.

1
Ic රිචර්ඩ් නිකල්ස් ගුආ Multimapsක්‍රමය වඩා හොඳ විකල්පයක් වන්නේ ඇයි? එය Mapවස්තුවක් ආපසු නොදෙන බැවින් එය අපහසුතාවයක් විය හැකිය .
ඔවුන්

160

සිතියමේ වටිනාකම ලෙස getName()යතුර සහ Choiceඑය භාවිතා කරන්න :

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));

19
පරිශීලකයාට තේරුම් ගත හැකි වන පරිදි කරුණාකර යම් විස්තරයක් ලියන්න.
මයාන්ක් ජේන්

4
මෙහි වැඩි විස්තර නොමැති වීම ඇත්තෙන්ම නරක ය, මන්ද මම මෙම පිළිතුරට වඩාත්ම කැමතියි.
මැඩ්කොනන්

Collectors.toMap(Choice::getName,c->c)(
අක්ෂර

7
එය choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice)); යතුර සඳහා පළමු ශ්‍රිතයට සමාන වේ , අගය සඳහා දෙවන ශ්‍රිතය
වෝටර්කාර්

17
දැකීම සහ තේරුම් ගැනීම කොතරම් පහසුදැයි මම දනිමි, c -> cනමුත් Function.identity()වඩා අර්ථකථන තොරතුරු රැගෙන යයි. මම සාමාන්‍යයෙන් ස්ථිතික ආනයනයක් භාවිතා කරමි, එවිට මට භාවිතා කළ හැකියidentity()
හැන්ක් ඩී

29

ඔබට Collectors.toMap () භාවිතා කිරීමට අවශ්‍ය නැතිනම් මෙන්න තවත් එකක්

Map<String, Choice> result =
   choices.stream().collect(HashMap<String, Choice>::new, 
                           (m, c) -> m.put(c.getName(), c),
                           (m, u) -> {});

1
Collectors.toMap()ඉහත උදාහරණයෙන් ඔබ පෙන්වා ඇති පරිදි එවකට භාවිතා කිරීමට වඩා හොඳ හෝ අපේම හැෂ්මැප් කුමක්ද?
ස්වප්නිල් ගැන්ග්‍රේඩ්

1
මෙම උදාහරණය සිතියමේ වෙනත් දෙයක් ස්ථානගත කරන්නේ කෙසේද යන්නට උදාහරණයක් සපයයි. ක්‍රම ඇමතුමකින් ලබා නොදුන් අගයක් මට අවශ්‍ය විය. ස්තූතියි!
th3morg

2
තෙවන තර්ක ශ්‍රිතය නිවැරදි නොවේ. එහිදී ඔබ හැෂ්මැප් දෙකක් ඒකාබද්ධ කිරීම සඳහා යම් කාර්යයක් සැපයිය යුතුය, එනම් හෂ්මාප් :: putAll
jesantana

26

ලැයිස්තුගත කර ඇති බොහෝ පිළිතුරු, ලැයිස්තුවේ අනුපිටපත් ඇති විට නඩුවක් මග හැරේ . එවැනි අවස්ථාවක දී පිළිතුර විසි කරනු ඇත IllegalStateException. ලැයිස්තු අනුපිටපත් හැසිරවීමට පහත කේතය බලන්න :

public Map<String, Choice> convertListToMap(List<Choice> choices) {
    return choices.stream()
        .collect(Collectors.toMap(Choice::getName, choice -> choice,
            (oldValue, newValue) -> newValue));
  }

19

සරල ආකාරයෙන් තවත් එක් විකල්පයක්

Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));

3
මෙම හෝ ජාවා 7 වර්ගය භාවිතා කිරීමේ ශක්‍ය වෙනසක් නොමැත.
අෂිෂ් ලොහියා

3
අනෙක් යාන්ත්‍රණයන්ට වඩා සිදුවෙමින් පවතින දේ කියවීමට සහ තේරුම් ගැනීමට මට මෙය පහසු විය
Freiheit

2
SO ඇසුවේ ජාවා 8 ප්‍රවාහ සමඟ ය.
මෙහරාජ් මලික්

18

උදාහරණයක් ලෙස, ඔබට වස්තු ක්ෂේත්‍ර සිතියමට පරිවර්තනය කිරීමට අවශ්‍ය නම්:

උදාහරණ වස්තුව:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getters and setters
    }

සහ මෙහෙයුම් ලැයිස්තුව සිතියමට පරිවර්තනය කරයි:

List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map<String,String> map = list.stream()
     .collect(Collectors.toMap(Item::getCode, Item::getName));

12

තෙවන පාර්ශවීය පුස්තකාල භාවිතා කිරීමට ඔබට අවශ්‍ය නැතිනම්, AOL හි සයික්ලොප්ස්-ප්‍රතික්‍රියා ලිබ් (මම දායකයෙකු බව අනාවරණය කිරීම) ලැයිස්තු සහ සිතියම ඇතුළුව සියලුම JDK එකතු කිරීමේ වර්ග සඳහා දිගු ඇත .

ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);

11

ඔබට IntStream භාවිතයෙන් දර්ශක ප්‍රවාහයක් සාදා ඒවා සිතියමකට පරිවර්තනය කළ හැකිය:

Map<Integer,Item> map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));

1
මෙය හොඳ විකල්පයක් නොවේ, මන්ද ඔබ සෑම මූලද්‍රව්‍යයක් සඳහාම () ඇමතුමක් ලබා දෙන අතර, එම නිසා මෙහෙයුමේ සංකීර්ණතාව වැඩි කරයි (අයිතම හැෂ්මැප් එකක් නම් o (n * k).
නිකොලස් නොබලිස්

O (1) හැෂ්මැප් එකකින් (i) ලබා ගත නොහැකිද?
අයිවෝ වැන් ඩර් වීකන්

VIvovanderVeeken කේත ස්නිපටයේ ලබා ගැනීම (i) ලැයිස්තුවේ ඇත, සිතියම නොවේ.
සාකි

Ak සාකි මම කතා කළේ නිකොලස්ගේ ප්‍රකාශය ගැන ය. අයිතමයන් ලැයිස්තුවක් වෙනුවට හැෂ්මැප් එකක් නම් මට n * k සංකීර්ණ බවක් නොපෙනේ.
අයිවෝ වැන් ඩර් වීකන්

10

මම මෙය කිරීමට උත්සාහ කළ අතර, ඉහත පිළිතුරු භාවිතා කරමින් Functions.identity(), සිතියමේ යතුර සඳහා භාවිතා කරන විට, යතුරු this::localMethodNameලියනය කිරීමේ ගැටළු නිසා ඇත්ත වශයෙන්ම වැඩ කිරීමට කැමති දේශීය ක්‍රමයක් භාවිතා කිරීමේ ගැටළු මට ඇති බව මට පෙනී ගියේය.

Functions.identity()ඇත්ත වශයෙන්ම මෙම අවස්ථාවේදී යතුරු ලියනය කිරීමට යමක් කරයි, එම නිසා ක්‍රමය ක්‍රියාත්මක වන්නේ නැවත පැමිණ Objectපරාමිතියක් පිළිගැනීමෙන් පමණිObject

මෙය විසඳීම සඳහා, මම ඒ වෙනුවට වළවල් දැමීම Functions.identity()හා භාවිතා කිරීම අවසන් කළෙමි s->s.

එබැවින් මගේ කේතය, ඩිරෙක්ටරියක් තුළ ඇති සියලුම නාමාවලි ලැයිස්තුගත කිරීම සඳහා වන අතර, සෑම කෙනෙකුම නාමාවලියෙහි යතුර ලෙස නාමාවලිය භාවිතා කර ඉන්පසු නාමාවලි නාමය සහිත ක්‍රමයක් අමතා අයිතම එකතුවක් ආපසු ලබා දෙන බව පෙනේ:

Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));

8

මම භාවිතා සිතියම්ගත ලැයිස්තුව පරිවර්තනය කරන ආකාරය ලියන්න ඇත generics හා පාලනය සඳහා ප්රතිලෝම . හුදෙක් විශ්ව ක්රමය!

සමහර විට අපට පූර්ණ සංඛ්‍යා ලැයිස්තුවක් හෝ වස්තු ලැයිස්තුවක් තිබේ . එබැවින් ප්‍රශ්නය පහත දැක්වේ: සිතියමේ යතුර කුමක් විය යුතුද ?

අතුරු මුහුණතක් සාදන්න

public interface KeyFinder<K, E> {
    K getKey(E e);
}

දැන් පාලනයේ ප්‍රතිලෝම භාවිතා කරයි:

  static <K, E> Map<K, E> listToMap(List<E> list, KeyFinder<K, E> finder) {
        return  list.stream().collect(Collectors.toMap(e -> finder.getKey(e) , e -> e));
    }

උදාහරණයක් ලෙස, අපට පොත් වස්තු තිබේ නම්, මෙම පන්තිය සිතියම සඳහා යතුර තෝරා ගැනීමයි

public class BookKeyFinder implements KeyFinder<Long, Book> {
    @Override
    public Long getKey(Book e) {
        return e.getPrice()
    }
}

6

මම මෙම සින්ටැක්ස් භාවිතා කරමි

Map<Integer, List<Choice>> choiceMap = 
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));

11
groupingBya Map<K,List<V>>නොව a නිර්මාණය කරයි Map<K,V>.
ක්‍රිස්ටෝෆර් හාමර්ස්ට්‍රෝම්

3
උල්ප්ස් ඩුප් පිළිතුරු. සහ, String getName();(පූර්ණ සංඛ්‍යා නොවේ)
බැරට්

5
Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));

4

මෙය ක්‍රම 2 කින් කළ හැකිය. එය නිරූපණය කිරීම සඳහා අප භාවිතා කිරීමට යන පන්තිය පුද්ගලයාට ඉඩ දෙන්න.

public class Person {

    private String name;
    private int age;

    public String getAge() {
        return age;
    }
}

සිතියමට පරිවර්තනය කළ යුතු පුද්ගලයින්ගේ ලැයිස්තුව පුද්ගලයන්ට ඉඩ දෙන්න

1. ලැයිස්තුවේ සරල පුරෝකථනය සහ ලැම්බඩා ප්‍රකාශනය භාවිතා කිරීම

Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));

2. ලබා දී ඇති ලැයිස්තුවේ අර්ථ දක්වා ඇති එකතු කරන්නන් එකතු කිරීම.

 Map<Integer,List<Person>> mapPersons = 
           persons.stream().collect(Collectors.groupingBy(Person::getAge));

4

මෙය සිදු කිරීම සඳහා ධාරාවන් භාවිතා කළ හැකිය. පැහැදිලිව භාවිතා කිරීමේ අවශ්‍යතාවය ඉවත් කිරීම සඳහා Collectors, toMapසංඛ්‍යානමය වශයෙන් ආනයනය කළ හැකිය (Java ලදායී ජාවා නිර්දේශිත පරිදි, තෙවන සංස්කරණය).

import static java.util.stream.Collectors.toMap;

private static Map<String, Choice> nameMap(List<Choice> choices) {
    return choices.stream().collect(toMap(Choice::getName, it -> it));
}


3
Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));

මා වෙනුවෙන් මෙම අරමුණු ඉටු කරයි,

Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
            (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));

3

එකම යතුරු නාමය සඳහා වන සෑම නව අගයක්ම අභිබවා යා යුතු නම්:

public Map < String, Choice > convertListToMap(List < Choice > choices) {
    return choices.stream()
        .collect(Collectors.toMap(Choice::getName,
            Function.identity(),
            (oldValue, newValue) - > newValue));
}

සියලු තේරීම් නමක් සඳහා ලැයිස්තුවකට කාණ්ඩගත කළ යුතු නම්:

public Map < String, Choice > convertListToMap(List < Choice > choices) {
    return choices.stream().collect(Collectors.groupingBy(Choice::getName));
}

1
List<V> choices; // your list
Map<K,V> result = choices.stream().collect(Collectors.toMap(choice::getKey(),choice));
//assuming class "V" has a method to get the key, this method must handle case of duplicates too and provide a unique key.


-1
String array[] = {"ASDFASDFASDF","AA", "BBB", "CCCC", "DD", "EEDDDAD"};
    List<String> list = Arrays.asList(array);
    Map<Integer, String> map = list.stream()
            .collect(Collectors.toMap(s -> s.length(), s -> s, (x, y) -> {
                System.out.println("Dublicate key" + x);
                return x;
            },()-> new TreeMap<>((s1,s2)->s2.compareTo(s1))));
    System.out.println(map);

ප්‍රකාශන යතුර AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CCCC, 3 = BBB, 2 = AA}


2
ඔබ මෙහි කුමක් කිරීමට උත්සාහ කරනවාද ?? ඔබ ප්‍රශ්නය කියෙව්වාද?
navderm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.