在Java中删除列表

Guf*_*oru 3 java list

Data用Java 创建了一个类.这是这个简单帮助类的源代码:

class Data {

    private Integer x;
    private Integer y;

    Data(Integer x, Integer y) {
        this.x = x;
        this.y = y;
    }

    protected Integer get_x() {
        return x;
    }

    protected Integer get_y() {
        return y;
    }

}
Run Code Online (Sandbox Code Playgroud)

之后我用我的班级Data来创造一些List<Data> container.我containeradd方法的帮助下添加了我的元素并对List进行排序.最后我打印输出:

for(Data data : container){
    System.out.println("Print x: " + data.get_x() + ", Print y: " + data.get_y()); 
}
Run Code Online (Sandbox Code Playgroud)

可能的输出可能是:

Print x: 1, Print y: 3
Print x: 1, Print y: 5
Print x: 1, Print y: 2
Print x: 1, Print y: 4
Print x: 1, Print y: 5
Print x: 1, Print y: 2
Print x: 1, Print y: 6
Print x: 1, Print y: 7
Print x: 2, Print y: 3
Print x: 2, Print y: 5
Print x: 2, Print y: 2
Print x: 2, Print y: 4
Print x: 2, Print y: 5
Print x: 2, Print y: 2
Print x: 2, Print y: 6
Print x: 2, Print y: 7
...
Run Code Online (Sandbox Code Playgroud)

每个唯一x部分的长度可以变化,我也不需要知道,x我的列表中有多少不同的值.现在我的问题是:是否可以创建另一个列表(或修改此列表),列表中只有有限和固定数量的顶部 x值并删除另一个?例如,我希望每个x值只有3个值.输出应该是:

Print x: 1, Print y: 3
Print x: 1, Print y: 5
Print x: 1, Print y: 2
Print x: 2, Print y: 3
Print x: 2, Print y: 5
Print x: 2, Print y: 2
Run Code Online (Sandbox Code Playgroud)

Tun*_*aki 5

解决方案是为a List<Data>中的每个x值存储a Map<Integer, List<Data>>.

Map<Integer, List<Data>> map = new HashMap<>();
for (Data data : container) {
    List<Data> value = map.get(data.get_x());
    if (value == null) {
        map.put(data.get_x(), new ArrayList<>(Arrays.asList(data)));
    } else if (value.size() < 3) {
        value.add(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此代码中,我们遍历所有数据并检索当前x数据的当前列表.如果它为null,则表示当前没有值,因此我们添加一个仅包含当前数据的新列表(包装Arrays.asList为new,ArrayList因为它返回固定大小的列表).否则,如果列表少于3个元素,那么我们添加当前的元素.

这将仅保留每个x值的前3个元素.


使用Java 8,这个循环可以简化一点:

Map<Integer, List<Data>> map = new HashMap<>();
for (Data data : container) {
    List<Data> list = map.computeIfAbsent(data.get_x(), k -> new ArrayList<Data>());
    if (list.size() < 3) {
        list.add(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想拥有List所有的值(而不是a Map),有一种更简单的方法(使用Java 8):保持Map<Integer, Integer>每个x值的映射与它出现的次数:

Map<Integer, Integer> map = new HashMap<>();
List<Data> filtered = new ArrayList<>();
for (Data data : container) {
    int count = map.merge(data.get_x(), 1, Integer::sum);
    if (count < 3) {
        filtered.add(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

filtered列表将包含想要的结果.在此代码中,map.merge如果没有映射则插入1,否则将1添加到先前的映射.