我有一个<LinearLayout
android:id="@+id/remote_button_layout"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginTop="30dp"
android:background="@drawable/btn_remote_button"
android:orientation="horizontal">
<TextView
android:text="Example Text"
android:textSize="10sp"
android:fontFamily="@font/mmedium"
android:textAllCaps="false"
android:layout_width="125dp"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="@android:color/secondary_text_light"/>
<Button
android:id="@+id/btn_remote_button"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_marginEnd="5dp"
android:background="@drawable/btn_remote_button"
android:drawableStart="@drawable/logo"
app:layout_constraintHorizontal_bias="1.0" />
</LinearLayout>
e想要转换为
List<Employee>
,其中外部字符串应为“名称”,内部字符串应为“域”。
Map<String, Map<String,Emp>>
我尝试了以下操作-
Name Id Domain
e(0) - Emp1, 1, Insurance
e(1) - Emp1, 2, Sales
e(2) - Emp2, 3, Sales
e(3) - Emp4, 4, Marketing
因此预期的输出图应该看起来像
e.stream().collect(Collectors.groupingBy(
Employee::getName,
toMap(Employee::getDomain,Emp)));
但是我只能得到唯一的值,实际输出-
<Emp1>
<Insurance, e(0)>
<Sales, e(1)>
<Emp2>
<Sales, e(2)>
<Emp4>
<Marketing, e(3)>
有人可以告诉最好的方法吗?
答案 0 :(得分:1)
您最需要的是嵌套分组,例如:
Map<String, Map<String, List<Employee>>> groupedMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain, Collectors.toList())));
注意-值为List<Employee>
,它们是按名称然后按域分组的员工。 (两个都合并成一个列表。)
如果您要严格遵守与指定分组相对应的单个雇员的做法,则只需进行少量修改即可对我的代码起作用:
Map<String, Map<String, Employee>> groupedReducedMap = employees.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.toMap(Employee::getDomain,
Function.identity(), // value as the employee instance
(a, b) -> a))); // choose first instance for similar 'domain'
答案 1 :(得分:0)
由于输出应为Map<String, Map<String,Employee>>
而不是Map<String, Map<String,List<Employee>>>
(即,根据您请求的输出,不能有两个Employee
具有相同的名称和相同的域),因此您可以将两个groupingBy
链接起来,然后使用reducing
确保每个内部组将只有一个Employee
而不是List<Employee>
:
Map<String, Map<String,Optional<Employee>>> output =
e.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain,
Collectors.reducing((x1,x2)->x2))));
此版本reducing
的问题在于,即使我们知道Optional<Employee>
永远不会为空,它也会返回Employee
而不是Optional
。
我们可以通过以下方法解决此问题:
Map<String, Map<String,Employee>> output =
e.stream()
.collect(Collectors.groupingBy(Employee::getName,
Collectors.groupingBy(Employee::getDomain,
Collectors.reducing(e.get(0),
(x1,x2)->x2))));
现在,我们使用具有标识值的reducing
的变体,向其传递任意Employee
实例(这无关紧要,因为它将始终被正确的实例替换) )。