Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8比较同一列表中的对象(数组索引超出范围)_Java_Java 8_Java Stream - Fatal编程技术网

Java 8比较同一列表中的对象(数组索引超出范围)

Java 8比较同一列表中的对象(数组索引超出范围),java,java-8,java-stream,Java,Java 8,Java Stream,我有一个带有键的hashmap,值为Map。在值对象,即列表中我必须比较每个对象。如果对象的任何两个属性名“TradeType”相同,那么我必须从列表中删除这两个。我正在努力实现以下目标。但是我得到了“数组索引越界异常”还有没有更好的方法来使用streams比较列表中的相同对象 Map<String,List<Trade>> tradeMap = new HashMap<>(); // Insert some data here tradeMap.entryS

我有一个带有键的hashmap,值为
Map
。在值对象,即
列表中
我必须比较每个对象。如果对象的任何两个属性名“TradeType”相同,那么我必须从列表中删除这两个。我正在努力实现以下目标。但是我得到了“数组索引越界异常”还有没有更好的方法来使用streams比较列表中的相同对象

Map<String,List<Trade>> tradeMap = new HashMap<>();
// Insert some data here
tradeMap.entrySet()
        .stream()
        .forEach(tradeList -> {
             List<Trade> tl = tradeList.getValue();
             String et = "";
         // Is there a better way to refactor this? 
             for(int i = 0;i <= tl.size();i++){
                   if(i == 0) {
                       et = tl.get(0).getTradeType();
                   }
                   else {
                       if(et.equals(tl.get(i).getTradeType())){
                           tl.remove(i);
                       }
                   }
              }
        });
Map tradeMap=newhashmap();
//在这里插入一些数据
tradeMap.entrySet()文件
.stream()
.forEach(贸易清单->{
List tl=tradeList.getValue();
字符串et=“”;
//有没有更好的重构方法?
对于(int i=0;i
public void test(){
映射数据=新的HashMap();
List list1=数组。asList(新交易(“1”)、新交易(“2”)、新交易(“1”)、新交易(“3”)、新交易(“3”)、新交易(“4”);
List list2=数组。asList(新交易(“1”)、新交易(“2”)、新交易(“2”)、新交易(“3”)、新交易(“3”)、新交易(“4”);
数据。将(“a”,列表1);
数据。将(“b”,列表2);
Map resultMap=data.entrySet()
.stream()
.collect(Collectors.toMap(Entry::getKey,this::filterDuplicateListObjects));
resultMap.forEach((key,value)->System.out.println(key+“:”+value));
//不要忘记重写Trade类的toString()方法。
}
公共列表筛选器DuplicateListObjects(条目){
返回条目。getValue()
.stream()
.filter(trade->isDuplicate(trade,entry.getValue()))
.collect(Collectors.toList());
}
公共布尔值重复(交易,列表交易){
返回tradeList.stream()
.filter(t->!t.equals(贸易))
.noneMatch(t->t.getTradeType().equals(trade.getTradeType());
}

您的描述与您的代码不完全同步,因此我将提供两个解决方案,您可以选择您想要的解决方案

首先也是最重要的是,对于
IndexOutOfBoundsException
您可以通过将循环条件从
i l.size()>1)更改来解决它
.map(l->l.get(0))
.forEach(t->list.removeIf(trade->trade.getTradeType().equals(t.getTradeType());
}
Map tradeMap=new HashMap();
tradeMap.values()
.stream()
.forEach(交易->交易.stream()
.collect(收集器.groupingBy(Trade::getType))
.values()
.stream()
.filter(tradesByType->tradesByType.size()>1)
.flatMap(集合::流)
.forEach(trades::remove));

您的索引越界错误来自这里:
i将
列表转换为中间数据结构(
LinkedHashMap
)只是为了删除重复项并从中取回经过优化的
列表
。这是最好的选择吗?因为我在这里引起了您的注意,请您对我下面的答案进行评论。我非常欣赏您的SO答案(尤其是java-8)。:)为我提供的解决方案的最佳选择是使用
equals
hashcode
方法。但正如前面提到的“如果您不想重写equals和hashcode”,无论出于什么原因,使用
toMap
方法是另一种选择。@谢谢,我感谢您的好话。当你说“你能评论一下我下面的回答吗?”时,具体是关于什么?谢谢你的回答!但是,基于域类的一个属性的值定义域类实例的相等性可能不是其绝对相等性的标准。我的意思是,如果OP提到的两个列表对象相等的条件对于这个用例来说是定制的。实际平等的标准可能有完全不同的实现方式。在我之前的评论中,我想听听专家对我(对这个问题)的回答的看法(正如我在这里所注意到的)我最近开始学习Java 8,并回答了一些问题作为练习。我注意到您的代码执行的逻辑与其他答案不同,但我完全理解OP提到的“如果对象的任何两个属性名“TradeType”相同,那么我必须从列表中删除这两个。”。这就是为什么我在回答的第一段提到OP“您的描述与您的代码不完全同步……”。无论如何,我也更新了我的答案,以考虑到这条信息。顺便说一句,您可以对代码进行一些改进,但这是次要的,所以我们可以让它过去:)@Aominè,我刚刚看到了您的最后一次编辑。这是一些非常好的流媒体;)
Map<String,List<Trade>> tradeMap = new HashMap<>();
tradeMap.put("1",Arrays.asList(new Trade("A"),new Trade("B"),new Trade("A")));
tradeMap.put("2",Arrays.asList(new Trade("C"),new Trade("C"),new Trade("D")));

Map<String,Collection<Trade>> tradeMapNew = tradeMap.entrySet()
    .stream()
    .collect(Collectors.toMap(Entry::getKey,
                        e -> e.getValue().stream()                         //This is to remove the duplicates from the list.
                            .collect(Collectors.toMap(Trade::getTradeType,
                                        t->t,
                                        (t1,t2) -> t1,
                                        LinkedHashMap::new))
                            .values()));
{1=[A, B], 2=[C, D]}
public void test(){
    Map<String, List<Trade>> data = new HashMap<>();
    List<Trade> list1 = Arrays.asList(new Trade("1"), new Trade("2"), new Trade("1"), new Trade("3"), new Trade("3"), new Trade("4"));
    List<Trade> list2 = Arrays.asList(new Trade("1"), new Trade("2"), new Trade("2"), new Trade("3"), new Trade("3"), new Trade("4"));

    data.put("a", list1);
    data.put("b", list2);

    Map<String, List<Trade>> resultMap = data.entrySet()
                                             .stream()
                                             .collect(Collectors.toMap(Entry::getKey, this::filterDuplicateListObjects));

    resultMap.forEach((key, value) -> System.out.println(key + ": " + value));
    // Don't forget to override the toString() method of Trade class.
}

public List<Trade> filterDuplicateListObjects(Entry<String, List<Trade>> entry){
    return entry.getValue()
                .stream()
                .filter(trade -> isDuplicate(trade, entry.getValue()))
                .collect(Collectors.toList());
}

public boolean isDuplicate(Trade trade, List<Trade> tradeList){
    return tradeList.stream()
            .filter(t -> !t.equals(trade))
            .noneMatch(t -> t.getTradeType().equals(trade.getTradeType()));
}
tradeMap.values()
        .stream()
        .filter(list -> list.size() > 1)
        .forEach(T::accept);
private static void accept(List<Trade> list) {
      String et = list.get(0).getTradeType();
      list.subList(1, list.size()).removeIf(e -> e.getTradeType().equals(et));
}
@Override
public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;
     Trade trade = (Trade) o;
     return Objects.equals(tradeType, trade.tradeType);
}

@Override
public int hashCode() {
    return Objects.hash(tradeType);
}
private static void accept(List<Trade> list) {
        List<Trade> distinct = list.stream()
                .distinct()
                .collect(Collectors.toList());

        list.clear(); // clear list
        list.addAll(distinct);  // repopulate with distinct objects by tradeType
}
private static void accept(List<Trade> list) {
        Collection<Trade> distinct = list.stream()
                .collect(Collectors.toMap(Trade::getTradeType,
                        Function.identity(), (l, r) -> l, LinkedHashMap::new))
                .values();

        list.clear(); // clear list
        list.addAll(distinct);  // repopulate with distinct objects by tradeType    
}
private static void accept(List<Trade> list) {
       list.stream()
           .collect(Collectors.groupingBy(Trade::getTradeType))
           .values()
           .stream()
           .filter(l -> l.size() > 1)
           .map(l -> l.get(0))
           .forEach(t -> list.removeIf(trade -> trade.getTradeType().equals(t.getTradeType())));
}
Map<String, List<Trade>> tradeMap = new HashMap<>();

tradeMap.values()
    .stream()
    .forEach(trades -> trades.stream()
        .collect(Collectors.groupingBy(Trade::getType))
        .values()
        .stream()
        .filter(tradesByType -> tradesByType.size() > 1)
        .flatMap(Collection::stream)
        .forEach(trades::remove));