我正在编写一个Codec来处理使用定制有线协议通过TCP发送的消息.在解码过程中,我创建了许多Strings,BigDecimals和日期.客户端 - 服务器访问模式意味着客户端发出请求然后解码数千个响应消息是常见的,这会导致大量的重复 String s,BigDecimals等.
因此我创建了一个InternPool<T>允许我实习每类对象的类.在内部,池使用a WeakHashMap<T, WeakReference<T>>.例如:
InternPool<BigDecimal> pool = new InternPool<BigDecimal>();
...
// Read BigDecimal from in buffer and then intern.
BigDecimal quantity = pool.intern(readBigDecimal(in));
Run Code Online (Sandbox Code Playgroud)
我的问题:我使用InternPool的BigDecimal,但我应该还可以考虑使用它String 来代替 String的intern()方法,我相信使用的PermGen空间?使用PermGen空间有什么好处?
我目前正在构建一个LRU缓存,我需要存储最后N个插入的项目.项目将被频繁插入(即许多写入操作),并且读取操作通常将严格按顺序返回大量事件,尽管从高速缓存中的任意点开始.例如,假设缓存包含事件:
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
合法的读操作是通过事件返回迭代器[2, 3, 4].
由于读取操作可能是长期存在的,我想使用一种数据结构,我可以安全地迭代每次读取尝试的序列的逻辑副本,从而防止高速缓存读取阻止任何后续写入.但是,使用vanilla Java ArrayList或者LinkedList在制作完整副本时会产生很大的开销.
我的问题:是否有任何第三方Java库提供类似于Scala的不可变数据结构,因此修改数据结构的尝试返回一个新的不可变副本(实际上它基于原始数据结构,因此复制操作非常快)?显然,数据结构无法符合Java Collections API,因为add(T)需要返回新集合(而不是void)的操作.
(请不要评论/回答引用这个作为过早优化的情况.)
提前致谢.
注意
Guava ImmutableList几乎实现了我的需求:它允许您调用copyOf副本通常引用原始内容(避免执行实际副本).不幸的是,你不能走另一条路并将一个项目添加到列表中并返回包含新元素的副本.
根据这个维基百科条目:
"协议缓冲区与Facebook的Thrift协议非常相似,不同之处在于它不包含用于定义服务的具体RPC堆栈.由于协议缓冲区是开源的,因此出现了许多RPC堆栈以填补这一空白."
但是,没有引用RPC堆栈的示例.任何人都可以建议基于Java的RPC堆栈实现?
最近有一个问题是,在Java中将调用getter的结果分配给局部变量以避免多次调用同一个访问器是一个好主意.我找不到原来的帖子,但一致认为这通常不是必要的,因为Hotspot无论如何都会优化方法调用开销.
但是,采用这种技术避免多次演员的观点是什么?目前我面临以下选择:
if (a instanceof Foo) {
// Cast once and assign to local variable.
Foo foo = (Foo)a;
if (foo.getB() == 1 && foo.getC() == 2) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
要么
if (a instanceof Foo) {
// Cast twice making code compact but possibly less readable.
// Also, is there an overhead in multiple casts?
if (((Foo)a).getB() == 1 && ((Foo)a).getC() == 2) {
...
}
}
Run Code Online (Sandbox Code Playgroud) 我编写了一个使用Java NIO API执行非阻塞IO的服务器.我看到一种情况,即偶尔客户端应用程序突然关闭(例如由于断电)并且连接在服务器端保持打开状态.
一位同事遇到了同样的问题,并表示他使用心跳来检测这类事情,但我希望有一种更简单的方法.还有其他人遇到过这个问题吗?
一些附加信息:我当前的服务器设计将取消一个密钥,并IOException在尝试读/写操作时捕获时关闭相应的通道.这种方法似乎在99%的时间内起作用; 我只看到了一些连接似乎保持打开的情况.
我的应用程序提供了启动长时间运行任务的能力.当发生这种情况时,会产生无模式JDialog,显示任务的进度.我特意使对话框无模式,以允许用户在任务运行时与GUI的其余部分进行交互.
我面临的问题是,如果对话框隐藏在桌面上的其他窗口后面,则很难找到:任务栏上没有相应的项目(在Windows 7上),Alt +下也没有可见的图标标签菜单.
有没有一种解决这个问题的惯用方法?我考虑过WindowListener在应用程序中添加一个JFrame并使用它来将JDialog放到前台.然而,这可能会变得令人沮丧(因为可能这意味着JFrame会失去焦点).
我正在使用这里JScrollNavigator描述的组件,以便为我嵌入的大型"画布式"CAD组件提供导航窗口.JScrollPane
我已经尝试调整JScrollNavigator绘制画布的缩略图以向用户提供一些额外的上下文.但是,执行此操作会导致应用程序主框架的呈现损坏.具体来说,它是调用paint(Graphics)视口组件(即我的主画布)的动作,传入由此Graphics创建的对象BufferedImage导致后续显示损坏; 如果我评论这一行,一切正常.
以下是JScrollNavigator被覆盖的paintComponent方法:
@Override
protected void paintComponent(Graphics g) {
Component view = jScrollPane.getViewport().getView();
BufferedImage img = new BufferedImage(view.getWidth(), view.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
// Paint JScrollPane view to off-screen image and then scale.
// It is this action that causes the display corruption!
view.paint(g2d);
g2d.drawImage(img, 0, 0, null);
Image scaled = img.getScaledInstance(getWidth(), getHeight(), 0);
super.paintComponent(g);
g.drawImage(scaled, 0, 0, null);
}
Run Code Online (Sandbox Code Playgroud)
有没有人对腐败的原因有任何建议?我原本以为绘画到幕外图像应该对现有的绘画操作没有影响.
编辑 …
我有一个看似简单的问题,即将逗号分隔String为标记,在以下情况下输出应包含空标记:
String逗号中的第一个字符是逗号.String是逗号.例如,对于String:",abd,def,,ghi,"应该产生输出:{"", "abd", "def", "", "ghi", ""}.
我已经尝试使用String.split,Scanner并且StringTokenizer对于这一点,但每个给出不同的不希望的输出(下文实施例).有人可以建议一个优雅的解决方案,最好使用JDK类吗?显然我可以自己编写代码,但我觉得我错过了上述三种方法之一.请注意,分隔符是固定的,String但不一定是逗号,也不是单个字符.
示例代码
import java.util.*;
public class Main12 {
public static void main(String[] args) {
String s = ",abd,def,,ghi,";
String[] tokens = s.split(",");
System.err.println("--- String.split Output ---");
System.err.println(String.format("%s -> %s", s, Arrays.asList(tokens)));
for (int i=0; i<tokens.length; ++i) {
System.err.println(String.format("tokens[%d] = %s", i, tokens[i]));
}
System.err.println("--- Scanner Output ---");
Scanner sc …Run Code Online (Sandbox Code Playgroud) 是否可以配置java.util.logging来压缩日志文件,当它"滚动"到新的日志文件?例如,我的日志配置文件的摘录如下所示:
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.pattern = /blah.log
java.util.logging.FileHandler.limit = 10000000
java.util.logging.FileHandler.count = 5
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望将当前的日志消息写入blah.log.0,同时保留blah.log.1.gz,blah.log.2.gz等.
另请注意,我不希望使用其他日志框架.
我需要将a BigDecimal紧凑编码为a ByteBuffer来替换我当前的(垃圾)编码方案(将其写BigDecimal为UTF-8编码,String前缀为表示String长度的字节).
假设a BigDecimal实际上是一个整数值(在数学意义上)和相关的标度,我打算将标度写为单个字节,后跟VLQ编码的整数.这应该足以涵盖预期值的范围(即最大标度127).
我的问题:当遇到诸如10,000,000,000之类的大值时,将其编码为值为1显然是最佳的:1为10,而不是编码整数10,000,000,000,其标度为0(将占用更多字节).如何确定给定的最佳比例BigDecimal?...换句话说,我如何确定我设置的最小可能比例,BigDecimal而不必执行任何舍入?
请不要在答案中引用"过早优化"一词:-)
java ×10
swing ×2
awt ×1
bigdecimal ×1
caching ×1
casting ×1
concurrency ×1
immutability ×1
java-2d ×1
jdialog ×1
logging ×1
math ×1
nio ×1
permgen ×1
protocols ×1
rpc ×1
string ×1
string-split ×1
tcp ×1