Scala的集合提供了一种称为collect合并filter并map转换为单个方法的方法.在过滤Object集合以生成仅包含特定类型的集合的子集时,它尤其有用.
Java 8的Stream有没有这样的东西?
代码
class TestException extends Exception {
}
interface Task<E extends Exception> {
void call() throws E;
}
public class TaskPerformer {
/** performs a task in the proper context, rethrowing any exceptions the task declares */
private <E extends Exception> void perform(Task<E> task) throws E {
beforeTask();
try {
task.call();
} finally {
afterTask();
}
}
private void afterTask() {
// implementation elided (does not matter)
}
private void beforeTask() {
// implementation elided (does not matter)
}
public static …Run Code Online (Sandbox Code Playgroud) import java.util.Comparator;
import java.util.PriorityQueue;
public class TestPQ {
public static void main(String[] args){
Comparator<String> comparator = new StringLengthComparator();
PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator);
queue.offer("Short");
queue.offer("ABCahahahha");
queue.offer("lululu");
queue.stream().map( s-> {
System.out.println("queue: "+ s);
return s;
});
}
}
Run Code Online (Sandbox Code Playgroud)
我有这个代码,我希望我会看到"短片","lululu"和"ABCahahahha"被打印出来.但我没有看到他们.我的代码出了什么问题?编译很好.我正在使用java 8编译器和运行时.
假设我有这个课程:
public class Thing {
private BigDecimal field1;
private BigDecimal field2;
private BigDecimal otherField1;
private BigDecimal otherField2;
private BigDecimal otherField3;
}
Run Code Online (Sandbox Code Playgroud)
并且在另一个类I for--over a List<Thing> things,将field1和field2添加到迭代完成时返回的总和.
但我想要的是用Java流来实现这一目标.以下是我所拥有的 - 它的工作原理,但我觉得必须有一种方法可以将其浓缩为一个流:
public BigDecimal addFields(List<Thing> things) {
BigDecimal field1sum = things.parallelStream()
.filter(thing -> thing.getField1() != null)
.map(Thing::getField1)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal field2sum = things.parallelStream()
.filter(thing -> thing.getField2() != null)
.map(Thing::getField2)
.reduce(BigDecimal.ZERO, BigDecimal::add);
return field1sum.add(field2sum);
}
Run Code Online (Sandbox Code Playgroud)
我怀疑答案是reduce()采用三个参数的方法,其中一个是BiFunction,但我无法弄清楚如何使其工作.编辑:我想我会在传递(x,y) -> x.add(y)到reduce(),但接下来的问题是如何做我map()这两个领域?
另外,是否有可能/如何将此命令式代码转换为功能流?
public BigDecimal addOtherFields(List<Thing> things) {
BigDecimal …Run Code Online (Sandbox Code Playgroud) @FunctionalInterface
public interface GenericFunctionalInterface {
public <T> T genericMethod();
}
Run Code Online (Sandbox Code Playgroud)
我有@FunctionalInterface,它有一个通用的方法.
如何使用和Lambda表达式来表示此接口?
我尝试下面的代码,但它不起作用,
GenericFunctionalInterface gfi = () -> {return "sss";};
Run Code Online (Sandbox Code Playgroud)
我遇到了编译错误:非法的lambda表达式:GenericFunctionalInterface类型的方法genericMethod是通用的
我在哪里可以放置类型信息?
我知道java中的lambda不能抛出一个已检查的异常,但可以抛出RuntimeException,但为什么下面的代码需要括号?
Map<String, Integer> m = new HashMap<>();
Integer integer = m.computeIfAbsent("", s -> {throw new IllegalArgumentException("fail");});
Run Code Online (Sandbox Code Playgroud)
你为什么不能拥有?
m.computeIfAbsent("", s -> throw new IllegalArgumentException("fail"));
Run Code Online (Sandbox Code Playgroud)
是因为编译器假设它会在这个实例中返回一个int,所以即使抛出它也不能返回异常?
我正在尝试创建一个包含活动和该活动总持续时间的地图,因为该活动在不同持续时间下会出现更多次。
通常,我会这样解决:
Map<String,Duration> result2 = new HashMap<String,Duration>();
for(MonitoredData m: lista)
{
if(result2.containsKey(m.getActivity())) result2.replace(m.getActivity(),result2.get(m.getActivity()).plus(m.getDuration()));
else result2.put(m.getActivity(), m.getDuration());
}
Run Code Online (Sandbox Code Playgroud)
但是我试图通过流来做到这一点,但是我不知道如何将总和放入其中。
Function<Duration, Duration> totalDuration = x -> x.plus(x);
Map<String, Duration> result2 = lista.stream().collect(
Collectors.groupingBy(MonitoredData::getActivity,
Collectors.groupingBy(totalDuration.apply(), Collectors.counting()))
);
Run Code Online (Sandbox Code Playgroud)
我尝试了各种方式将它们分组,直接映射或直接将它们汇总在方括号中,但我陷入了困境。
下面的代码有效,但是我收到SonarLint的通知,因为我在流中使用了一个匿名类而不是lambda表达式,我没有看到如何改进下面的代码来避免通知:
Properties prop = new Properties();
Properties temp = new Properties();
//... add some values and keys in prop and temp
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map( new Function<Entry<Object, Object>, Entry<String, String>>(){
@Override
public Entry<String, String> apply(Entry<Object, Object> entry) {
return new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
};
}
})
.collect(Collectors.toMap(Entry<String,String>::getKey, Entry<String,String>::getValue)));
Run Code Online (Sandbox Code Playgroud)
代码的解释:
我使用java.util中的属性类,不幸的是entrySet …
声纳显示
使这个基于值的字段瞬态,因此它不包含在此类的序列化中.
这是一个面向未来的错误,当基于价值的类将被释放时.
那么,如果应用程序永远不依赖于它的对象标识,那么我可以使基于值的对象非瞬态吗?
java-8 ×9
java ×6
java-stream ×6
lambda ×5
dictionary ×1
eclipse ×1
generics ×1
interface ×1
java-9 ×1
sonarlint ×1