Java ArrayList添加具有相同Id的值

Java ArrayList添加具有相同Id的值,java,arraylist,collections,Java,Arraylist,Collections,因此,我有一个数组列表,看起来像这样:,我应该找到具有相同id的所有元素,并将这些值相加到结果数组列表中(值总是在id之后)。起初,我认为问题很简单,于是继续尝试: List<String> resultList = new ArrayList<>(); for(int i = 0; i < myList.size(); i+=2){ BigInteger currentID = new BigInteger

因此,我有一个数组列表,看起来像这样:
,我应该找到具有相同id的所有元素,并将这些值相加到结果数组列表中(值总是在id之后)。起初,我认为问题很简单,于是继续尝试:

        List<String> resultList = new ArrayList<>();
        for(int i = 0; i < myList.size(); i+=2){

            BigInteger currentID = new BigInteger(myList.get(i));
            BigInteger currentSum = new BigInteger(myList.get(i+1));
            String currentId = myList.get(i);
            int j = 2;

            while(j < myList.size()){
                if(currentId.equals(myList.get(j))){
                 BigInteger value2 = new BigInteger(myList.get(j+1));
                 currentSum = currentID.add(value2);
                }
                resultList.add(currentId);
                resultList.add(String.valueOf(currentSum));
                j+=2;
            }
        }
List resultList=new ArrayList();
对于(int i=0;i

不用说这是不正确的,其中一个问题是已经添加在一起的值将被读取到结果数组中,因此我认为它们应该在循环中以某种方式被删除。你们有什么建议吗

假设您可以使用地图: 我最初的想法是使用
Map Map=newhashmap()

作为代码(注意:未经测试,可能无法编译,不会直接复制和粘贴):

Map Map=newhashmap();
对于(int i=0;i
然后,您可以获取生成的
映射
,并将其转换回列表中。
我将让您编写代码,以获取映射中的每个条目,并将其添加到新列表中。谷歌在这方面很有帮助

如果你想使用流,你可以这样做

给出如下列表:

      List<BigInteger> list = List.of(1,10,3,20,3,40,1,5,4,7,1,8,4,9,6,20)
           .stream().mapToLong(a -> a).mapToObj(
                  BigInteger::valueOf).collect(Collectors.toList());
您可以停在那里,只使用地图,也可以将它转换为一个列表,就像您开始使用的交替
id/value
对列表一样

       List<BigInteger> listfinal = mapfinal
            .entrySet()
            .stream()
            .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
            .collect(Collectors.toList());
[1,23,3,60,4,16,6,20]


使用
地图
最容易做到这一点。但是它也可以在不改变输入数据结构或使用任何中间数据结构的情况下完成

这是一个未经测试的代码示例。我使用
List

List myList=。。。
List resultList=new ArrayList();
对于(int i=0;i

这个解决方案是
O(N^2)
。由于您实际上使用的是
String
biginger
而不是
Integer
,这使得它更加昂贵

使用
Map
的解决方案应为
O(NlogN)
O(N)
,具体取决于Map类型


旁白:在某些情况下,如果在第一个内部循环中使用
resultList
而不是
myList
,速度会更快。但是我在上面做的方式更明显

您是否仅限于使用列表?你能用地图来代替吗?不,我能把这个字符串arrylist改成地图吗?你也可以用列表来实现你想做的事情,即使这是地图的完美场景。这里的错误源是您对每个条目再次使用while循环进行迭代。嵌套的while循环毫无意义。@main.c-我认为您误解了这些问题。您需要为同一个id累积所有值。这就是内部循环试图做的。
      List<BigInteger> list = List.of(1,10,3,20,3,40,1,5,4,7,1,8,4,9,6,20)
           .stream().mapToLong(a -> a).mapToObj(
                  BigInteger::valueOf).collect(Collectors.toList());
      Map<BigInteger, BigInteger> mapfinal =
            IntStream.iterate(0, i -> i < list.size(), i -> i += 2).mapToObj(
                  i -> new BigInteger[] { list.get(i), list.get(i + 1)
                  }).collect(Collectors.groupingBy(i -> i[0],
                        Collectors.reducing(BigInteger.ZERO,
                              a -> a[1],
                              (a, b) -> a.add(b))));
       List<BigInteger> listfinal = mapfinal
            .entrySet()
            .stream()
            .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
            .collect(Collectors.toList());
      System.out.println(listfinal);
    List<Integer> myList = ...
    List<Integer> resultList = new ArrayList<>();

    for (int i = 0; i < myList.size(); i += 2) {
        int id = myList.get(i);

        // Check that we haven't accumulated this id already
        boolean seen = false;
        for (int j = 0; j < i && !seen; j += 2) {
            seen = myList.get(j) == id;
        }
        if (seen) {
            continue;
        }

        // Accumulate values for 'id'
        int sum = myList.get(i + 1);
        for (int j = i + 2; j < myList.size(); j += 2) {
            if (myList.get(j) == id) {
                sum += myList.get(j + 1);
            }
        }
        // Send to output ...
        resultList.add(id);
        resultList.add(sum);
    }