代码之家  ›  专栏  ›  技术社区  ›  kolocoda

按两个唯一属性筛选Java列表

  •  0
  • kolocoda  · 技术社区  · 7 年前

    id | seatNo | time | type
    === ======== ====== =====
    1  |   1    |   1  |  1  *
    2  |   2    |   1  |  1
    3  |   1    |   2  |  1  *
    4  |   2    |   2  |  1
    5  |   3    |   1  |  2  *
    6  |   4    |   1  |  2
    

    带星号(*)的行是时间和类型的唯一值。如何编写循环,根据时间和类型筛选此列表中的唯一对象。我试过这样的方法:

    int currentTime = 0;
    int currentType = 0;
    List<Bus> sortedBuses = new ArrayList<>();
    for (Bus bus : allSeats) {
        if (bus.getTime()!= currentTime && bus.getType != currentType) {
            sortedBuses.add(bus);
        }
        currentId = bus.getTime();
        currentType = bus.getType();
    }
    

    但这不能正确过滤。我只能获得独特的值,如where time&类型相同。欢迎任何能帮助我解决这个问题的想法。

    4 回复  |  直到 7 年前
        1
  •  0
  •   Karol Dowbecki    6 年前

    您必须对存储在中的总线进行过滤 sortedBuses

    List<Bus> sortedBuses = new ArrayList<Bus>();
    
    outerloop:
    for (Bus bus : allSeats) {
       for (Bus sorted : sortedBuses)
          if (bus.getTime()==sorted.getTime() && bus.getType == sorted.getType)
            continue outerloop;
       sortedBuses.add(bus);
    }
    
        2
  •  0
  •   KarelG    7 年前

    time type 字段中,我引入了一个字符串,可以将其读取为

    <time>_<type>
    

    然后,现在更容易找到独特的元素:

    List<String> foundTimeType = new ArrayList<String>(); // represents a list of known types
    List<Bus> sortedBuses = new ArrayList<>();
    for (Bus bus : allSeats) {
        String timeType = "" + bus.getTime() + "_" + bus.getType();
        // only add if timeType is not present in foundTimeType list
        if (! foundTimeType.contains(timeType)) {
            foundTimeType.add(timeType); // to keep it unique
            sortedBuses.add(bus);
        }
    }
    
        3
  •  0
  •   Frank    7 年前

    哈希集 在java中,默认情况下,此数据结构不会插入duplicate。当然,此机制仅适用于基本类型,对于自定义对象(如您的对象),您应该重写hashcode和equals方法以使该机制工作。

    public class Bus {
    
        private int type;
    
        private int time;
    
        public Bus(int type, int time) {
            // TODO Auto-generated constructor stub
                this.type = type;
                this.time = time;
        }
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public int getTime() {
            return time;
        }
    
        public void setTime(int time) {
            this.time = time;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + time;
            result = prime * result + type;
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Bus other = (Bus) obj;
            if (time != other.time)
                return false;
            if (type != other.type)
                return false;
            return true;
        }
    }
    

    你的主要目标是:

    import java.util.HashSet;
    
    
    public class Main {
    
        public Main() {
            // TODO Auto-generated constructor stub
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            HashSet<Bus> buses = new HashSet<Bus>();
            Bus b1 = new Bus(1, 1);
            Bus b2 = new Bus(1, 1);
            Bus b3 = new Bus(2, 1);
            Bus b4 = new Bus(2, 1);
            buses.add(b1);
            buses.add(b2);
            buses.add(b3);
            buses.add(b4);
    
            System.out.println("size: "+buses.size());
     for(Bus bus : buses) {
                System.out.println(bus.getTime()+" "+bus.getType());
                }
    
    
        }
    
    }
    

    size: 2
    1 1
    1 2
    

    compareTo(Object o) ,而不是可以使用HashSet 有序树 您将获得偶数排序数据结构。

        4
  •  0
  •   gil.fernandes    7 年前

    这可以使用流API在一行中解决,方法是将时间和类型收集到映射的键中,然后简单地导出值。键将包含时间和类型。

    线路为:

    buses.stream().collect(toMap(b -> String.format("%d_%d", b.getType(), b.getTime()), p -> p, (p, q) -> p))
                        .values();
    

    List<Bus> buses = Arrays.asList(new Bus(1, 1, 1), new Bus(2, 1, 1),
                    new Bus(3, 2, 1), new Bus(4, 2, 1),
                    new Bus(5, 1, 2), new Bus(6, 1, 2));
    Collection<Bus> res = buses.stream().collect(toMap(b -> String.format("%d_%d", b.getType(), b.getTime()), p -> p, (p, q) -> p))
                    .values();
    res.forEach(System.out::println);
    

    这将在控制台上打印:

    > Bus{id=1, type=1, time=1}
    > Bus{id=5, type=1, time=2}
    > Bus{id=3, type=2, time=1}