- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,我遇到一个问题,ArrayList 中存在特定类型的各种对象,如下所示,
...
//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);
现在,有多种情况我可以增加或减少:
例如
示例1:
如果我修改对象 h2
,使 h2
的开始时间 (16:30) 减少 10 分钟,然后结束时间h1
的值应减少相同的值,即 h1
结束时间将为 16:20
示例2:
如果我修改对象 h2
,使 h2
的结束时间 (16:45) 增加 10 分钟,即 16:55 那么对象 h3
应从列表中删除,因为它已被 h2
完全占用。
I/P:我总是在两个 diff 变量中修改每个对象的开始和结束时间,但问题是在运行时修改上述情况中提到的对象并相应地更新数组列表。
最佳答案
正确的方法是使用 TreeSet
并定义 Param
的排序。为此,您必须创建 Param
实现Comparable
然后提供 hashCode
的实现和equals
以及。
然后,您可以修改某个项目,然后导航该集合以查找前一个和后一个项目。我的解决方案假设没有任何重叠时间,并且它也会处理您的第二种情况(删除无效的时间片)。
首先我们需要 Param
实现Comparable<Param>
:
public class Param implements Comparable<Param> {
//Public just for demo purposes and brevity
public int start;
public int end;
public Param(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public int compareTo(Param o) {
//Needs to be consistent with equals!!
int result = this.start - o.start;
if(result == 0) {
result = (this.end - this.start) - (o.end - o.start);
}
return result;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + start;
result = 31 * result + end;
return result;
}
@Override
public boolean equals(Object o) {
... // null check, reference check etc.
Param p = (Param) o;
return this.start == p.start && this.end == p.end;
}
}
现在所有的辛苦工作都完成了!您可以使用 TreeSet
中的方法找到正确的项目然后修改它们。这是一些示例代码。
NavigableSet<Param> pset = new TreeSet<Param>();
Param p1 = new Param(10, 20);
Param p2 = new Param(20, 30);
Param p3 = new Param(30, 50);
Param p4 = new Param(50, 60);
pset.add(p1);
pset.add(p2);
pset.add(p3);
pset.add(p4);
System.out.println(pset);
int sdiff = -2;
int ediff = 2;
//Find the item we want, as well as the preceding and succeeding items
Param p = pset.floor(new Param(20, 30));
Param lower = pset.lower(p);
Param higher = pset.higher(p);
//Remove the item from the set and modify it
pset.remove(p);
p.start += sdiff;
p.end += ediff;
//Add only if it is valid
if(p.start < p.end) {
pset.add(p);
}
//If we have a preceding item
if(lower != null) {
//Remove, modify, and add back to set
pset.remove(lower);
lower.end += sdiff;
if(lower.start < lower.end) {
pset.add(lower);
}
}
//Same case as lower
if(higher != null) {
pset.remove(higher);
higher.start += ediff;
if(higher.start < higher.end) {
pset.add(higher);
}
}
System.out.println(pset);
运行这段代码给我们:
[[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]]
[[15, 30], [30, 50], [50, 60]]
还有:
int sdiff = 5;
int ediff = -10;
Param p = pset.floor(new Param(10, 20));
给我们:
[[10, 20], [20, 30], [30, 50], [50, 60]]
[[10, 30], [30, 50], [50, 60]]
如果您修改一个元素使其跨越多个切片,则此特定解决方案将不起作用。但通过稍加修改,您也可以让它处理这些情况。这就是使用排序结构真正有用的地方,因为使用列表来执行此操作将是一场噩梦。修改涉及使用 while
循环而不是 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;
}
例如,当您更改 [30, 40]
时,此算法将不起作用。成为[0, 5]
或[5, 15]
。在这种情况下,您最终会得到一个空格,其中 [30, 40]
过去是这样,并且没有明确定义如何填充该空间。应该[20, 30]
更改为 [20, 40]
,或者应该[40, 50]
更改为 [30, 50]
?或者像 [20, 35]
这样的东西怎么样?和[35, 50]
?只要修改后的范围包含原始范围的全部或部分,该算法就有效。
关于java - 维护可以修改的时间片的有序列表(列表仍应排序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31440885/
就类似于这个问题:mongodb query multiple pairs using $in 我想用 (first, last) >= ('John', 'Smith') 找到前 10 个全名。使用
如何保留向 NSDictionary 添加对象的方式? 我意识到 NSDictionary 中的值没有特定的顺序,但就我而言,我需要保留使用 setValue:forKey: 添加的顺序,例如一个数组
看看上证所运营商 CMPORDPS - ordered compare packed singles CMPUNORDPS - unordered compare packed singles 有序和
我使用 PowerMock 来模拟静态方法。我需要验证静态和非静态方法调用的顺序。可以使用 PowerMock 来做吗? UPD 我使用 powermockito 扩展来模拟静态方法,因此使用 pow
例如,如何合并两个已排序的整数流?我认为这是非常基本的,但只是发现它根本不是微不足道的。下面的不是尾递归的,当流很大时它会堆栈溢出。 def merge(as: Stream[Int], bs: St
我试图在二叉树中查找/打印每个节点的中序后继,但编译器给我的结果是段错误。 这是结构:- struct node { int x; struct node *left; str
我有一个查询看起来像 SELECT a, b, c, d FROM tab ORDER BY a ASC, b ASC 我的结果集看起来像 +-----------------
首先,我试过搜索这个主题但一无所获(似乎找不到合适的关键词),所以如果这是重复的,请告知。 我一直在尝试从我的数据库中获取一些 time_stamp 并将它们按时间间隔排序。例如,我运行一个查询,如
这个问题在这里已经有了答案: How do I get the index of an iterator of an std::vector? (9 个回答) 关闭 6 年前。 我已经订购了 QVe
我有以下实体,如果我尝试通过 removeTask 方法从 TaskList 中删除 Task,则会出现异常。 @Entity public class TaskList extends Generi
所以,我对 C 编程还是很陌生。 有3个长度相同的字符串。 str1="abc", str2="def", str3="ghi". 新字符串中的输出将类似于“adgbehcfi”。 #include
我的查询有一个问题,它花费的时间太长(仅仅这个简单的查询就超过了两秒)。 乍一看,这似乎是一个索引问题,所有连接的字段都已编入索引,但我找不到其他我可能需要编入索引以加快速度的内容。一旦我将我需要的字
我正在寻找一个 Map 实现,它按照键值对的添加顺序迭代它们。例如 Map orderedMap = // instantiation omitted for obvious reasons :) o
我正在寻找具有以下功能的数据库系统: 分层(多维)键 每个维度的键排序 因此,如果我的 key 类似于 App > User > Item,我可以运行如下查询:“该用户的下一项是什么?”或者“这个应用
以下类使用 CRTP 尝试将类型添加到具有 Schwarz 计数器以确保初始化顺序的 std::vector。根据 3.6.2/2 成员 h_ 具有无序初始化。我将如何更改它以确保它已订购初始化?我希
我正在实现一个玩具调度程序,它读取进程规范(例如到达时间、总运行时间)的输入文件,然后根据随机 io/cpu 突发调度进程。 文件格式 Arrival time, total CPU time, CP
我目前正在使用 python 2.7 requests 库,并且不支持有序 header 。我可以为 post 和 get 放置有序数据(如有序字典),但根本不支持标题。甚至在 python 3 中也
我正在使用来自 google guava 的 ConcurrentHashMap(通过 MapMaker),但该实现未排序。google guava 中有 ConcurrentSkipListMap,
我有一个旧应用程序,其中使用 ConcurrentHashMap。现在我们知道并发HasMap 是无序的,但是需要读取最初插入的对象。我已经在生产中使用了一段时间的代码,因此我正在寻找快速替代方案来替
最近我开始使用 .NET Core 2.1 开发一个新项目,我决定使用 SOLID 原则并创建一个漂亮的项目结构。 这是一个 Web API 项目。一切正常我使用了很多依赖注入(inject),大部分
我是一名优秀的程序员,十分优秀!