有没有人知道一个库或者至少有一些关于在Java中创建和使用持久数据结构的研究?我没有将持久性称为长期存储,而是将持久性称为不变性(参见维基百科条目).
我正在探索为持久性结构建模api的不同方法.使用构建器似乎是一个有趣的解决方案:
// create persistent instance
Person p = Builder.create(Person.class)
.withName("Joe")
.withAddress(Builder.create(Address.class)
.withCity("paris")
.build())
.build();
// change persistent instance, i.e. create a new one
Person p2 = Builder.update(p).withName("Jack");
Person p3 = Builder.update(p)
.withAddress(Builder.update(p.address())
.withCity("Berlin")
.build)
.build();
Run Code Online (Sandbox Code Playgroud)
但这仍然有点像锅炉板.有任何想法吗?
我试图继承str,但由于其不变性而遇到一些困难.
class DerivedClass(str):
def __new__(cls, string):
ob = super(DerivedClass, cls).__new__(cls, string)
return ob
def upper(self):
#overridden, new functionality. Return ob of type DerivedClass. Great.
caps = super(DerivedClass, self).upper()
return DerivedClass(caps + '123')
derived = DerivedClass('a')
print derived.upper() #'A123'
print type(derived.upper()) #<class '__main__.DerivedClass'>
print derived.lower() #'a'
print type(derived.lower()) #<type 'str'>
Run Code Online (Sandbox Code Playgroud)
对于不需要任何新功能的继承方法,例如derived.lower(),是否有一种简单的pythonic方法来返回类型的对象DerivedClass(而不是str)?或者我是否像我一样手动覆盖每个str.method()derived.upper()?
编辑:
#Any massive flaws in the following?
class DerivedClass(str):
def __new__(cls, string):
ob = super(DerivedClass, cls).__new__(cls, string)
return ob
def …Run Code Online (Sandbox Code Playgroud) 我最近一直在阅读有关函数式语言的文章.在10多年的OO开发过程中,我发现很难理解人们如何能够指出纯粹的功能方法(即使用相同参数调用相同的方法做同样的事情) (在OO程序中)我需要缓存数据.
我们是否承认在程序中可能需要一个不可变的actor(即缓存).我刚看了Joe Armstrong关于infoq的演讲,他在这方面看起来很教条!
我们是否只是承认查找数据可能很昂贵(因为我们永远无法缓存它)?如果是这样,我们如何控制,例如,某些共享资源(例如数据库)上的负载
是否有一些神奇的尘埃,我还不知道,这解决了整个问题,然后喝了一杯好茶.
当然谷歌搜索"Erlang Cache"似乎返回了一些公平的结果......
我正在尝试优化PostgreSQL 9.1.2中的复杂查询,它调用了一些函数.这些函数标记为STABLE或IMMUTABLE,并在查询中使用相同的参数多次调用.我假设PostgreSQL足够智能,只能为每组输入调用一次 - 毕竟,这是STABLE和IMMUTABLE的重点,不是吗?但似乎多次调用这些函数.我写了一个简单的函数来测试它,它证实了这一点:
CREATE OR REPLACE FUNCTION test_multi_calls1(one integer)
RETURNS integer
AS $BODY$
BEGIN
RAISE NOTICE 'Called with %', one;
RETURN one;
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;
WITH data AS
(
SELECT 10 AS num
UNION ALL SELECT 10
UNION ALL SELECT 20
)
SELECT test_multi_calls1(num)
FROM data;
Run Code Online (Sandbox Code Playgroud)
输出:
NOTICE: Called with 10
NOTICE: Called with 10
NOTICE: Called with 20
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?如何让它只执行一次该功能?
我经常听到"无国籍"和"不可改变"这个词.例如,HTTP是无状态协议,String对象是不可变对象.但我很难掌握两者之间的差异.当我创建无状态对象时,它不会在内部存储任何"状态"数据.如果我创建一个Immutable对象,它意味着它永远不会改变.
这是不是意味着同样的事情?
由于不可变对象不会改变,因此根据定义它不能具有状态.它永远是它.如果一个对象没有状态,则不能进行变异(根据定义).因此,并非所有无状态对象都是不可变和不可变对象无状态的吗?
什么可以是可变无状态对象或不可变状态对象的示例?
使用不可变对象变得越来越普遍,即使手头的程序从不打算并行运行.然而,我们仍然使用getter,每个字段需要3行样板,每次访问需要5个额外字符(用你最喜欢的主流OO语言).虽然这看起来微不足道,而且许多编辑无论如何都会从程序员那里消除大部分负担,但这似乎仍然是不必要的努力.
继续使用访问器与不可变对象的直接字段访问的原因是什么?具体来说,强制用户使用访问者(对于客户端或库编写者)是否有优势,如果是这样,他们是什么?
请注意,我指的是不可变对象,不像这个问题,它通常引用对象.要清楚,不可变对象上没有setter.
这个Java教程 说不可变对象在创建后不能改变它的状态.
java.lang.String 有一个领域
/** Cache the hash code for the string */
private int hash; // Default to 0
Run Code Online (Sandbox Code Playgroud)
在hashCode()方法的第一次调用时初始化,因此它在创建后更改:
String s = new String(new char[] {' '});
Field hash = s.getClass().getDeclaredField("hash");
hash.setAccessible(true);
System.out.println(hash.get(s));
s.hashCode();
System.out.println(hash.get(s));
Run Code Online (Sandbox Code Playgroud)
产量
0
32
Run Code Online (Sandbox Code Playgroud)
调用Stringimmutable 是否正确?
我一直在使用番石榴的已经ImmutableMap有Builder一段时间没有过多考虑如何/为什么它的工作原理.我一直在以Javadoc描述的方式使用构建器:
ImmutableMap<String, Integer> WORD_TO_INT =
new ImmutableMap.Builder<String, Integer>()
.put("one", 1)
.put("two", 2)
.put("three", 3)
.build();
Run Code Online (Sandbox Code Playgroud)
我也在其他地方看到过这种语法的例子:
ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
.put("one", 1)
.put("two", 2)
.put("three", 3)
.build();
Run Code Online (Sandbox Code Playgroud)
两者似乎都产生完全相同的结果.
快速浏览一下ImmutableMap 源表明builder()第二个例子中的静态调用返回:new Builder<K, V>()
这两种方法之间似乎没有任何功能差异.
引擎盖下有什么不同吗?有理由偏好其中一个吗?
编辑:添加字节码差异.
除了一行之外,生成的字节码几乎相同:
方法1(Builder<K,V>):
static {};
0 new com.google.common.collect.ImmutableMap$Builder [12]
3 dup
4 invokespecial com.google.common.collect.ImmutableMap$Builder() [14]
7 ldc <String "key1"> [17]
........
Run Code Online (Sandbox Code Playgroud)
方法2 :( <K,V>builder())
static {};
0 invokestatic com.google.common.collect.ImmutableMap.builder() …Run Code Online (Sandbox Code Playgroud) 例如:
public string ReplaceXYZ(string text)
{
string replacedText = text;
replacedText = replacedText.Replace("X", String.Empty);
replacedText = replacedText.Replace("Y", String.Empty);
replacedText = replacedText.Replace("Z", String.Empty);
return replacedText;
}
Run Code Online (Sandbox Code Playgroud)
如果我甚至为不包含"X","Y"或"Z"的字符串调用"ReplaceXYZ",每次会创建3个新字符串吗?
我在其中一个项目中发现了与此类似的代码.它被重复调用,因为它循环遍历大量字符串.
将我的项目更新为Spring Boot 1.5.10后,Lombok停止了与Jackson的正常工作.我的意思是不可变的DTO创建,当我的对象中的字段名称与json请求中的字段不同时:
@Value
@Builder
public class MyImmutableDto implements Serializable {
@JsonProperty("other-field-1-name")
private final BigDecimal myField1;
@JsonProperty("other-field-2-name")
private final String myField2;
and a lot of fields there...
}
Run Code Online (Sandbox Code Playgroud)
因此,在将Spring Boot更新到1.5.10之后,这段代码无效,我需要像这样配置lombok:
lombok.anyConstructor.addConstructorProperties = true
Run Code Online (Sandbox Code Playgroud)
有没有人知道用jackson + lombok创建这样的对象没有这个lombok修复的任何其他方法?我可以使用以下代码代替此修复程序:@JsonPOJOBuilder和@JsonDeserialize(builder = MyDto.MyDtoBuilder.class):
@Value
@Builder
@JsonDeserialize(builder = MyDto.MyDtoBuilder.class)
public class MyDto implements Serializable {
// @JsonProperty("other-field-1-name") // not working
private final BigDecimal myField1;
private final String myField2;
private final String myField3;
and a lot of fields there...
@JsonPOJOBuilder(withPrefix = "")
public …Run Code Online (Sandbox Code Playgroud) immutability ×10
java ×5
oop ×2
c# ×1
c++ ×1
erlang ×1
function ×1
guava ×1
inheritance ×1
jackson ×1
lombok ×1
object ×1
overriding ×1
performance ×1
postgresql ×1
python ×1
spring-boot ×1
stateless ×1
string ×1