Java 获取所有副本
例如,我有一个对象列表Java 获取所有副本,java,spring,data-structures,Java,Spring,Data Structures,例如,我有一个对象列表 List myList=new ArrayList(); 添加(新文件(“TypeA”); myList.add(新文档(“TypeB”); 添加(新文件(“TypeA”); 添加(新文件(“TypeA”); myList.add(新文档(“TypeB”); 现在每个文档都有一个不同的类型属性,这就是我传递给构造函数的属性(这不是真实情况,只是试图简化它) 我需要做的是,为所有具有相同类型的文档对象添加一个新属性“counter”。因此,具有“TypeA”的三个文档对象
List myList=new ArrayList();
添加(新文件(“TypeA”);
myList.add(新文档(“TypeB”);
添加(新文件(“TypeA”);
添加(新文件(“TypeA”);
myList.add(新文档(“TypeB”);
现在每个文档都有一个不同的类型属性,这就是我传递给构造函数的属性(这不是真实情况,只是试图简化它)
我需要做的是,为所有具有相同类型的文档对象添加一个新属性“counter”。因此,具有“TypeA”的三个文档对象需要具有递增的计数器值(1,2,3)。如果只有一个文档具有特定类型,则不应具有计数器值
所以我想我基本上需要以某种方式过滤(分组)它们,然后对它们进行迭代。但是我如何才能有效地做到这一点呢
我有JavaScript背景,这对我来说很容易,但对于Java,我发现的一切似乎都很复杂。例如,您可以使用存储计数的数据结构 Bag是一个集合,允许存储多个项目及其重复计数:
Bag<Integer> bag = new HashBag<>(
Arrays.asList(1, 2, 3, 3, 3, 1, 4));
assertThat(2, equalTo(bag.getCount(1)));
Bag-Bag=新的HashBag(
asList(1,2,3,3,3,1,4);
资产(2个,相等于(1个);
例如,您可以使用存储计数的数据结构 Bag是一个集合,允许存储多个项目及其重复计数:
Bag<Integer> bag = new HashBag<>(
Arrays.asList(1, 2, 3, 3, 3, 1, 4));
assertThat(2, equalTo(bag.getCount(1)));
Bag-Bag=新的HashBag(
asList(1,2,3,3,3,1,4);
资产(2个,相等于(1个);
您可以使用java stream api对文档类型进行分组计数:
final Map collect=myList.stream()
.collect(groupby(Document::getType,counting());
系统输出打印项次(收集);
另一个可能的选项是向文档类添加静态计数器:
类文档{
私有静态映射计数器=new HashMap();
公共文档(字符串类型){
compute(type,(k,v)->(v==null)?1:v+1);//为新类型设置counter=1,为现有类型增加
}
...
}
您可以使用java stream api对文档类型进行分组计数:
final Map collect=myList.stream()
.collect(groupby(Document::getType,counting());
系统输出打印项次(收集);
另一个可能的选项是向文档类添加静态计数器:
类文档{
私有静态映射计数器=new HashMap();
公共文档(字符串类型){
compute(type,(k,v)->(v==null)?1:v+1);//为新类型设置counter=1,为现有类型增加
}
...
}
在每个文档中都有一个字段计数器听起来像是一个糟糕的设计,因为您必须更新每个添加的新对象上的所有引用,或者最糟糕的是,更新静态字段。您应该将不可变设计作为一个好的做法
以下是完成这项工作的方法
Map<String, Long> documentCount = myList.stream().collect(groupingBy(Document::getType, counting()));
Map<String, Long> filteredDocumentCount = documentCount.entrySet().stream().filter(x -> x.getValue() > 1).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map documentCount=myList.stream().collect(groupingBy(Document::getType,counting());
Map filteredocumentcount=documentCount.entrySet().stream().filter(x->x.getValue()>1).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
或者更具表现力的版本:
Map<String, Long> documentCount = myList.stream().collect(groupingBy(Document::getType, counting()));
Predicate<Map.Entry<String,Long>> moreThanOneOccurrence = x -> x.getValue() > 1;
Map<String, Long> filteredDocumentCount = documentCount.entrySet().stream().filter(moreThanOneOccurrence).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map documentCount=myList.stream().collect(groupingBy(Document::getType,counting());
谓词morethaneoneoccurrence=x->x.getValue()>1;
Map filteredocumentcount=documentCount.entrySet().stream().filter(不止一次出现).collector(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
在每个文档中都有一个字段计数器听起来像是一个糟糕的设计,因为您必须更新每个添加的新对象上的所有引用,或者最糟糕的是,更新静态字段。您应该将不可变设计作为一个好的做法
以下是完成这项工作的方法
Map<String, Long> documentCount = myList.stream().collect(groupingBy(Document::getType, counting()));
Map<String, Long> filteredDocumentCount = documentCount.entrySet().stream().filter(x -> x.getValue() > 1).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map documentCount=myList.stream().collect(groupingBy(Document::getType,counting());
Map filteredocumentcount=documentCount.entrySet().stream().filter(x->x.getValue()>1).collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
或者更具表现力的版本:
Map<String, Long> documentCount = myList.stream().collect(groupingBy(Document::getType, counting()));
Predicate<Map.Entry<String,Long>> moreThanOneOccurrence = x -> x.getValue() > 1;
Map<String, Long> filteredDocumentCount = documentCount.entrySet().stream().filter(moreThanOneOccurrence).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map documentCount=myList.stream().collect(groupingBy(Document::getType,counting());
谓词morethaneoneoccurrence=x->x.getValue()>1;
Map filteredocumentcount=documentCount.entrySet().stream().filter(不止一次出现).collector(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
可以这样做的一种方法是,您可以维护一个映射对象,类型作为键,运行计数器作为值。然后查找此映射并适当分配计数器属性,并在现有类型的新Dicument添加到列表中时更新映射。可以这样做的一种方法是维护映射对象使用类型作为键,运行计数器作为值的ct。然后查找此映射并适当分配计数器属性,并在列表中添加现有类型的新Dicument时更新映射。流解决方案非常优雅,但对初学者来说有很多魔力。有点(乏味)我想,您可以使用merge:counter.merge(type,1,Integer::sum)
,而不是compute
。流解决方案非常优雅,但对初学者来说有很多魔力。有点(乏味)我想,您可以使用merge:counter.merge(type,1,Integer::sum)来代替compute
。