Java 转换列表<;字符串>;映射<;字符串,字符串>;在爪哇

Java 转换列表<;字符串>;映射<;字符串,字符串>;在爪哇,java,list,hashmap,java-stream,Java,List,Hashmap,Java Stream,我想将一个列表转换为一个映射,其中键只是一个计数器,它需要遵循列表的顺序。我目前有以下代码: private static Map<String, String> convertListToMap(final List<String> list) { AtomicInteger counter = new AtomicInteger(0); Map<String, String> map = list.stream().collect(Coll

我想将一个列表转换为一个映射,其中键只是一个计数器,它需要遵循列表的顺序。我目前有以下代码:

private static Map<String, String> convertListToMap(final List<String> list) {
    AtomicInteger counter = new AtomicInteger(0);
    Map<String, String> map = list.stream().collect(Collectors.toMap((c) -> {
        Integer integer = counter.incrementAndGet();
        return integer.toString();
    }, (c) -> c));

    return map;
}
私有静态映射convertlistomap(最终列表){
AtomicInteger计数器=新的AtomicInteger(0);
Map Map=list.stream().collect(Collectors.toMap((c)->{
整数=计数器。incrementAndGet();
返回整数.toString();
},(c)->c);
返回图;
}
我有两个问题:

  • 在我桌面上的一个简单控制台应用程序测试中,计数器保留列表的顺序。我们能确保在其他地方执行时,订单始终保持不变吗
  • 有没有更好的编码方法
    您可能可以使用
    IntStream
    将索引映射为值的键,并使用
    LinkedHashMap
    来保持顺序

        IntStream.range(0, list.size())
                 .mapToObj(i -> new AbstractMap.SimpleEntry<>(String.valueOf(i+1), list.get(i)))
                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> 1, LinkedHashMap::new));
    
    IntStream.range(0,list.size())
    .mapToObj(i->new AbstractMap.SimpleEntry(String.valueOf(i+1),list.get(i)))
    .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(a,b)->1,LinkedHashMap::new));
    
    这样试试

    static Map<String, String> convert(List<String> list) {
        return IntStream.range(0, list.size()).boxed()
                .collect(Collectors.toMap(n -> String.valueOf(n+1), list::get,
                        (a, b) -> a, LinkedHashMap::new));
    }
    
    静态映射转换(列表){
    返回IntStream.range(0,list.size()).boxed()
    .collect(Collectors.toMap(n->String.valueOf(n+1)),list::get,
    (a,b)->a,LinkedHashMap::new);
    }
    
    注:

    • 合并函数
      (a,b)->a
      并不是真正起作用的
    • LinkedHashMap::new
      的供应商确保保留订单。遗憾的是,没有一个
      Collector.toMap
      允许供应商
      不使用
      merge
      功能

    关于您的第一个问题:只要您的号码不变,您的订单将保留。更好的解决方案是LinkedList(),其中条目按您添加它们的顺序排序(可能更容易,我不知道您的应用程序)


    关于您的第二个问题:AtomicInteger主要是由于更好的线程安全性()而进步的。如果您没有执行任何并发操作,那么应该没有明显的差异。因此,可以使用正整数。

    lambda引用的局部变量必须是有效的最终变量。正常的整数是如何工作的?所有正确实现的
    列表
    实现都保留插入顺序,而不仅仅是
    链接列表
    。问题1本质上要求的是与我编辑的第二个问题相同的东西,使其更通用,而不是要求不使用AtomicInteger的解决方案。抱歉搞混了,谢谢。这比使用原子整数好吗?或者这两种方法都一样好,只是偏好的问题?AtomicInteger主要用于线程之间竞争唯一值的情况。除非您使用的是线程(甚至可能是线程),否则您不必担心这一点。原子*方法在确保线程安全方面确实会产生一些开销。@Naman Nope。我喜欢。我必须记住在适用时使用方法引用。我并不总是想到这些。谢谢@纳曼:事实上,我必须改变现状。OP将
    AtomicInteger
    初始化为0,但使用incrementAndGet使其变为1。因此,我假设第一个数字一定是1。但我仍然需要流中的0来获取列表的第一个值。而且
    rangeClosed
    方法使最后一个索引太长。@WJS有意义,要获取的索引与存储在地图中的索引不同,造成混淆。返回类型
    Map
    将与方法签名不兼容,除非使用
    String.valueOf
    Map
    操作将使其不正确,因为您无法
    列表中获取
    (新的AbstractMap.SimpleEntry(i,10)
    部分)。它可能会非常接近我编辑的,但如果在下一步中要收集它,则不需要映射到
    SimpleEntry