鉴于以下列表:
List<String> list = new ArrayList<String>();
list.add("s1");
list.add("s2");
list.add(null);
list.add("s3");
list.add(null);
list.add("s4");
Run Code Online (Sandbox Code Playgroud)
我需要一个删除空引用的辅助类.就像是:
SomeHelper.removeNullReference(名单);
这样列表只包含"s1","s2","s4","s4"(非空引用).
我应该用什么来满足这个要求?
我的表:
产品:id,名称
优惠:id,value,product_id
实体:
@Entity
@Table(name="product")
public class Product implements Serializable {
@OneToMany(mappedBy="product")
private Set<Offer> offers;
...
}
@Entity
@Table(name="offer")
public class Offer implements Serializable {
@ManyToOne
@JoinColumn(name="PRODUCT_ID")
private Product product;
...
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从表中获取一些数据时Product,我得到一个java.lang.NullPointerException,并且这段代码:product.getOffers()返回:
{IndirectSet:未实例化}
如何解决这个问题?
在检测到我的某个Web服务中存在缺陷后,我将错误跟踪到以下单行:
return this.getTemplate().getDomains().stream().anyMatch(domain -> domain.getName().equals(name));
Run Code Online (Sandbox Code Playgroud)
当我肯定地知道域名列表包含一个名称等于提供的域名时,该行返回false name.所以在我搔了一会儿之后,我最终分开整条线来看看发生了什么.我在调试会话中得到以下内容:
请注意以下行:
List<Domain> domains2 = domains.stream().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
根据调试器,domains是一个包含两个元素的列表.但申请后,.stream().collect(Collectors.toList())我得到一个完全空的名单.如果我错了,请纠正我,但根据我的理解,那应该是身份操作并返回相同的列表(如果我们是严格的话,还是它的副本).那么这里发生了什么?
在你问之前:不,我根本没有操纵过截图.
为了将其置于上下文中,此代码在有状态请求范围EJB中使用JPA管理实体执行,并在扩展持久性上下文中具有字段访问权限.在这里,您可以获得与手头问题相关的代码的一些部分:
@Stateful
@RequestScoped
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class DomainResources {
@PersistenceContext(type = PersistenceContextType.EXTENDED) @RequestScoped
private EntityManager entityManager;
public boolean templateContainsDomainWithName(String name) { // Extra code included to diagnose the problem
MetadataTemplate template = this.getTemplate();
List<Domain> domains = template.getDomains();
List<Domain> domains2 = domains.stream().collect(Collectors.toList());
List<String> names = domains.stream().map(Domain::getName).collect(Collectors.toList());
boolean exists1 = names.contains(name);
boolean exists2 = this.getTemplate().getDomains().stream().anyMatch(domain -> domain.getName().equals(name));
return this.getTemplate().getDomains().stream().anyMatch(domain -> domain.getName().equals(name));
} …Run Code Online (Sandbox Code Playgroud) 通常承认,通过继承扩展接口的实现不是最佳实践,并且该组合(例如,从头开始再次实现接口)更加可维护.
这是有效的,因为接口契约迫使用户实现所有所需的功能.但是在java 8中,默认方法提供了一些可以"手动"覆盖的默认行为.请考虑以下示例:我想设计一个用户数据库,该数据库必须具有List的功能.出于效率目的,我选择通过ArrayList来支持它.
public class UserDatabase extends ArrayList<User>{}
Run Code Online (Sandbox Code Playgroud)
这通常不被认为是一种很好的做法,如果真的希望列表的全部功能并遵循通常的"遗产构成"的座右铭,我宁愿这样做:
public class UserDatabase implements List<User>{
//implementation here, using an ArrayList type field, or decorator pattern, etc.
}
Run Code Online (Sandbox Code Playgroud)
但是,如果不注意,则不需要覆盖某些方法,例如spliterator(),因为它们是List接口的默认方法.问题是,List的spliterator()方法执行得比ArrayList的spliterator()方法差得多,后者已针对ArrayList的特定结构进行了优化.
这迫使开发者
所以问题是:在这种情况下,人们应该更喜欢构成而不是继承吗?
我有JPA实体,列表如下:
@OneToMany(mappedBy = "scadaElement", orphanRemoval = true)
private List<ElementParameter> elementParameters;
Run Code Online (Sandbox Code Playgroud)
和地图形式ElementParameter
@ManyToOne
@JoinColumn(name = "SCADAELEMENT_ID")
ScadaElement scadaElement;
Run Code Online (Sandbox Code Playgroud)
当我获得带有elementParameters列表的实体并对其执行流时,即使我使用.size()触发列表时,也不执行任何操作,但是当我使用for循环执行相同操作时,它也能正常工作.
System.out.println("elements size: " + s.getElementParameters().size());
s.getElementParameters()
.stream()
.forEach(
a -> {
System.out.println("elementId: " + a.getId());
}
);
Run Code Online (Sandbox Code Playgroud)
是否有任何解决方案可以使该流工作?我使用eclipselink作为JPA提供者.
@Entity
@NamedQueries({
@NamedQuery(
name = "FolderNode.findByName",
query = "SELECT f FROM FolderNode f WHERE f.name = :name AND f.parentNode = :parentNode"),
@NamedQuery(
name = "FolderNode.findRootNodeByName",
query = "SELECT f FROM FolderNode f WHERE f.name = :name AND f.parentNode is null")
})
public class FolderNode extends InstructorTreeNode {
public FolderNode() {
super();
}
public FolderNode(String name) {
this();
setName(name);
}
public FolderNode(int sortOrder, String name) {
this(name);
this.sortOrder = sortOrder;
}
public FolderNode(int sortOrder, String name, EmployeeState status) {
this(sortOrder, name); …Run Code Online (Sandbox Code Playgroud) 一本书的问题:
在过去(Java 8之前版本),您被告知将方法添加到接口是一种糟糕的形式,因为它会破坏现有代码.现在您被告知可以添加新方法,前提是您还提供默认实现.
- 这有多安全?描述接口的新
stream方法Collection导致遗留代码编译失败的情况.- 二进制兼容性怎么样?来自JAR文件的遗留代码是否仍会运行?"
我的答案如下,但我不太确定.
stream和相同签名的方法时(例如,在实现的遗留类中Collection),它才是安全的.否则,这个旧的遗留代码将无法编译. 任何人都可以确认或拒绝这些答案,或者只是为这些答案添加更多参数,参考或清晰度吗?
我正在使用Java 8(build 1.8.0_25),Netbeans 8.0.2,并将一些Java 8功能集成到现有应用程序中.排序和.forEach不起作用,所以我创建了一些测试代码,以确保我理解lambdas等,并诊断问题.下面是新代码和代码的混合,以便与我的系统中的数据进行交互:
public void test(Registration reg) {
/* new code */
List<String> family = new ArrayList<>();
family.add("Mom");
family.add("Dad");
family.add("Brother");
family.add("Sister");
family.forEach(p -> System.out.println(p));
Collections.sort(family, (p1,p2) -> {
System.out.println(p1 + " <==> "+ p2);
return p1.compareToIgnoreCase(p2);
});
family.forEach(p -> System.out.println(p));
/* code to test with my system data */
List<RegistrationItem> item = new ArrayList<>();
List<RegistrationItem> regI = reg.getRegistrationItem();
regI.forEach(p -> {
System.out.println(p.toString());
item.add(p);
});
Collections.sort(regI, (r1,r2) -> {
System.out.println(r1.toString() + r2.toString());
return r1.getId().compareTo(r2.getId());
});
for (RegistrationItem r : …Run Code Online (Sandbox Code Playgroud) java ×8
java-8 ×5
jpa ×4
collections ×2
java-stream ×2
composition ×1
eclipselink ×1
entity ×1
inheritance ×1
java-ee ×1
jax-rs ×1
one-to-many ×1
sorting ×1