根据唯一值将List拆分为子列表

时间:2015-03-11 17:12:47

标签: java arraylist java-8 classification decision-tree

我有一份清单清单: List<ArrayList<String>> D = new ArrayList<>();

当它被填充时,它可能看起来像:
[&#34; A&#34;,&#34; B&#34;,&#34; Y&#34;]
[&#34; C&#34;,&#34; D&#34;,&#34; Y&#34;]
[&#34; A&#34;,&#34; D&#34;,&#34; N&#34;]

我想根据唯一属性值将列表列表拆分为分区(让我们说索引1)。

因此索引1处的属性有两个唯一值,&#34; B&#34;和&#34; D&#34;,所以我想分成:
[&#34; A&#34;,&#34; B&#34;,&#34; Y&#34;]

[&#34; C&#34;,&#34; D&#34;,&#34; Y&#34;]
[&#34; A&#34;,&#34; D&#34;,&#34; N&#34;]

并将其放入List<ArrayList<ArrayList<String>>> sublists;

有这样做的聪明方法,还是我只做这样的事情:

List<ArrayList<ArrayList<String>>> sublists = new ArrayList<>();
int featIdx = 1;

// generate the subsets
for (ArrayList<String> record : D) {
    String val = record.get(featIdx);

    // check if the value exists in sublists
    boolean found = false;
    for (ArrayList<ArrayList<String>> entry : sublists) {
        if (entry.get(0).get(featIdx).equals(val)) {
            entry.add(record);
            found = true;
            break;
        }
    }

    if (!found) {
        sublists.add(new ArrayList<>());
        sublists.get(sublists.size()-1).add(record);
    }
}

这是C4.5决策树algorithm的一个步骤,所以如果有人有这方面的经验,如果您能告诉我这是否是生成子列表的正确方法,我将不胜感激。

谢谢。

2 个答案:

答案 0 :(得分:5)

使用Java 8,您可以使用groupingBy收集器:

Map<String, List<List<String>>> grouped = D.stream()
                .collect(Collectors.groupingBy(list -> list.get(1)));
Collection<List<List<String>>> sublists = grouped.values();

或@AlexisC建议:

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;

Collection<List<List<String>>> sublists = D.stream()
             .collect(collectingAndThen(groupingBy(list -> list.get(1)), Map::values));

答案 1 :(得分:2)

我建议创建HashMap<String, List<List<String>>>,然后将这些列表分组。然后,只需致电map.values()即可获得Collection<List<List<String>>>

List<List<String>> list = new ArrayList<>();
list.add(Lists.newArrayList("A", "B", "Y"));
list.add(Lists.newArrayList("C", "D", "Z"));
list.add(Lists.newArrayList("A", "D", "X"));
list.add(Lists.newArrayList("D", "C", "A"));

Map<String, List<List<String>>> mapped = list.stream()
                .collect(Collectors.groupingBy(li -> li.get(1))); 
System.out.println(mapped);
Collection<List<List<String>>> groupedList = mapped.values();