Java 维护可修改时间片的有序列表(列表仍应有序)

Java 维护可修改时间片的有序列表(列表仍应有序),java,collections,Java,Collections,因此,我有一个问题,即在数组列表中存在特定类型的各种对象,如下所示 ... //Class definition class Params { long startTimeMillis; long endTimeMillis; String currentState; .. correponding getters and setters are present here .. } .... ArrayList<Params> activities=new Arra

因此,我有一个问题,即在数组列表中存在特定类型的各种对象,如下所示

...
//Class definition
class Params
{
  long startTimeMillis;
  long endTimeMillis;
  String currentState;

 .. correponding getters and setters are present here ..
}
....

ArrayList<Params> activities=new ArrayList<>();

Params h1= new Params();        
h1.setStartTimeMillis(1435939200000L);//"16:00"
h1.setEndTimeMillis(1435941000000L);//"16:30"
h1.setCurrentState("C");

Params h2= new Params();        
h2.setStartTimeMillis(1435941000000L);//"16:30"
h2.setEndTimeMillis(1435941900000L);//"16:45"
h2.setCurrentState("B");

Params h3= new Params();        
h3.setStartTimeMillis(1435941900000L);//"16:45"
h3.setEndTimeMillis(1435942500000L);//"16:55"
h3.setCurrentState("A");

Params h4= new Params();        
h4.setStartTimeMillis(1435942500000L);//"16:55"
h4.setEndTimeMillis(1435942800000L);//"17:00"
h4.setCurrentState("B");

Params h5= new Params();        
h5.setStartTimeMillis(1435942800000L);//"17:00"
h5.setEndTimeMillis(1435943400000L);//"17:10"
h5.setCurrentState("C");

activities.add(h1);
activities.add(h2);
activities.add(h3);
activities.add(h4);
activities.add(h5);
。。。
//类定义
类参数
{
长Starttimillis;
长端时间毫秒;
字符串当前状态;
…这里有对应的接受者和接受者。。
}
....
ArrayList活动=新建ArrayList();
Params h1=新的Params();
h1.设置开始时间毫秒(143593900000L)//"16:00"
h1.setEndTimeMillis(14359410000毫升)//"16:30"
h1.设置当前状态(“C”);
Params h2=新的Params();
h2.设置起始时间毫秒(14359410000000L)//"16:30"
h2.setEndTimeMillis(143594100000L)//"16:45"
h2.设置当前状态(“B”);
参数h3=新参数();
h3.设置起始时间毫秒(1435941900000L)//"16:45"
h3.setEndTimeMillis(1435945000L)//"16:55"
h3.设置当前状态(“A”);
参数h4=新参数();
h4.设置开始时间毫秒(1435945000L)//"16:55"
h4.setEndTimeMillis(14359428000000L)//"17:00"
h4.设置当前状态(“B”);
参数h5=新参数();
h5.setStartTimeMillis(14359428000000L)//"17:00"
h5.setEndTimeMillis(143594340000L)//"17:10"
h5.设定电流状态(“C”);
增加(h1);
活动。添加(h2);
活动。添加(h3);
增加(h4);
活动。添加(h5);
现在,在各种情况下,我可以增加或减少:

  • 特定对象的开始时间
  • 特定对象的结束时间
  • 如果对象存在于两个或多个活动之间,则两者都存在
e、 g

例1:

如果我修改对象
h2
,使
h2
16:30)的开始时间减少10分钟,则
h1
的结束时间应减少相同的时间,即
h1
结束时间应为16:20

例2:

如果我修改对象
h2
,使
h2
16:45)的结束时间增加10分钟,即16:55,则对象
h3
应从列表中删除,因为它完全被
h2
占用

I/p:
我总是在两个不同的变量中修改每个对象的开始和结束时间,但问题是在运行时按照上述情况修改对象,并相应地更新arraylist。

这将修改您的开始时间

public void modifyStart(Params toModify,int increment,ArrayList<Params> list){
    int index = list.indexOf(toModify);
    int timeStart=toModify.getStartTimeMillis()+increment;
    toModify.setStartTimeMillis(timeStart);
    for(int i=index-1;i>=0;i--){ //removing all previous
        if(timeStart<list.get(i).getStartTimeMillis()){
            list.remove(i);
            index--;
        }else{
             break;
        }
    }
    if(index==0){
        return;
    }
    Params previous = list.get(index-1);
    previous.setEndTimeMillis(previous.getEndTimeMillis()+increment);
    if(toModify.getStartTimeMillis()>toModify.getEndTimeMillis()){ //removes yourself
        list.remove(toModify);
    }
}
public void modifyStart(参数toModify,int增量,数组列表){
int index=list.indexOf(toModify);
int timeStart=toModify.getStartTimeMillis()+增量;
toModify.setStartTimeMillis(timeStart);
对于(inti=index-1;i>=0;i--){//删除所有以前的
如果(timeStarttoModify.getEndTimeMillis()){//删除您自己
列表。删除(toModify);
}
}
结束时间将非常相似


注意:没有测试,只是展示一个想法。正确的方法是使用
TreeSet
并定义
Param
的顺序。要做到这一点,您必须使
Param
实现
可比性
,然后提供
hashCode
等于
的实现

然后,您可以修改一个项目,然后在集合中导航以查找前面和后面的项目。我的解决方案假设没有任何重叠时间,它也将处理第二种情况(删除无效时间片)

首先,我们需要有
Param
实现
可比较的

运行此代码将为我们提供:

[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 22], [22, 28], [28, 50], [50, 60]]
此代码适用于无效的时间片,以下示例将演示:

int sdiff = -20;
int ediff = 20; 
产出:

[[10, 20], [20, 30], [30, 50], [50, 60]]
[[0, 50], [50, 60]]
如果您修改了元素本身,使其时间片无效,那么它也会起作用:

int sdiff = 5;
int ediff = -5;      

Param p = pset.floor(new Param(10, 20));
给了我们:

[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 22], [22, 28], [28, 50], [50, 60]]
[[10, 20], [20, 30], [30, 50], [50, 60]]
[[15, 30], [30, 50], [50, 60]]
[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 30], [30, 50], [50, 60]]
以及:

给了我们:

[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 22], [22, 28], [28, 50], [50, 60]]
[[10, 20], [20, 30], [30, 50], [50, 60]]
[[15, 30], [30, 50], [50, 60]]
[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 30], [30, 50], [50, 60]]
如果您修改元素使其跨越多个切片,则此特定解决方案将不起作用。但只需稍加修改,您也可以使其处理这些情况。这就是使用排序结构真正有帮助的地方,因为使用列表执行此操作将是一场噩梦。修改涉及使用
while
loop而不是
if
,只要有需要修改的元素,就在循环中运行。循环还会检查我们是否在切片的“中间”结束,如果是,它会适当调整开始/结束时间:

//As long as we have elements to modify
while(lower != null) {
    Param nextLower = null;

    //Remove, modify, and add back to set if valid
    pset.remove(lower);
    lower.end += sdiff;

    if(lower.start < lower.end) {
        //The modified slice is valid, so add it back
        pset.add(lower);                   
    } else if(lower.start > lower.end) {
        //The modified slice is not valid and so we're not
        //going to add it. But it looks like we might have
        //encroached on the space of the slice that precedes
        //"lower" (at least; we may have extended past even
        //more, possibly all the way up to and past the
        //beginning)
        nextLower = pset.lower(p);
        if(nextLower != null && p.start == nextLower.start) {
            //It looks like we took up the space of the preceding
            //slice exactly (i.e., we are flush against it) and
            //so we don't need to do anything.
            nextLower = null;
        } else if(nextLower != null) {
            //It looks like we took up the space of the preceding
            //slice and then some. Let's adjust sdiff to reflect
            //that.
            sdiff = p.start - nextLower.end;                  
        }                            
    }

    lower = nextLower;
}

  //Similar to lower
  while(higher != null) {
      Param nextHigher = null;

      pset.remove(higher);
      higher.start += ediff;

      //Need to check for the additional case where the modified element's
      //end time could supersede a "higher" element's end time.
      if(higher.start < higher.end && higher.end > p.end) {
          pset.add(higher);              
      } else if(higher.start > higher.end || higher.end <= p.end) {
          nextHigher = pset.higher(p);
          if(nextHigher != null && p.end == nextHigher.start) {
              nextHigher = null;
          } else if(nextHigher != null) {
              ediff = p.end - nextHigher.start;                  
          }
      }

      higher = nextHigher;
  }
//只要我们有需要修改的元素
while(较低!=null){
Param nextLower=null;
//删除、修改并添加回集合(如果有效)
pset.移除(降低);
低端+=sdiff;
如果(较低起点<较低终点){
//修改后的切片有效,因此请将其添加回
pset.add(较低);
}else if(lower.start>lower.end){
//修改后的切片无效,因此我们不可用
//我要加上,但看起来我们可能有
//侵占了前面切片的空间
//“较低”(至少;我们可能已经超过了
//更多,可能一直到过去
//(开始)
nextLower=设置较低(p);
if(nextLower!=null&&p.start==nextLower.start){
//看起来我们占用了前面的空间
//精确地切片(即,我们与之齐平)和
//所以我们什么都不需要做。
nextLower=null;
}else if(nextLower!=null){
//看起来我们占用了前面的空间
//切片,然后是一些。让我们调整sdiff以反映
//那个。
sdiff=p.start-nextLower.end;
}                            
}
更低=下一个更低;
}
//类似于较低的
while(更高!=null){
参数nextHigher=null;
pset.移除(更高);
较高的启动时间=ediff;
//需要检查修改的元素
//结束时间可以取代“更高”元素的结束时间。