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);
现在,在各种情况下,我可以增加或减少:
- 特定对象的开始时间
- 特定对象的结束时间
- 如果对象存在于两个或多个活动之间,则两者都存在
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;
//需要检查修改的元素
//结束时间可以取代“更高”元素的结束时间。