使用Stream API获取一对一映射时遇到一些麻烦。基本上,假设你上课了。
public class Item {
private final String uuid;
private Item(String uuid) {
this.uuid = uuid;
}
/**
* @return universally unique identifier
*/
public String getUuid() {
return uuid;
}
}
我希望Map<String, Item>
能够轻松查找。但是考虑到Stream<Item>
,似乎并不是一种简单的方法来获得Map<String, Item>
。
显然,Map<String, List<Item>>
无所谓:
public static Map<String, List<Item>> streamToOneToMany(Stream<Item> itemStream) {
return itemStream.collect(groupingBy(Item::getUuid));
}
这是更安全更普遍的情况,但我们做知道在这种情况下只会一对一。我无法找到任何可编译的内容 - 我特意尝试将downstream
参数设置为Collectors.groupingBy
。类似的东西:
// DOESN'T COMPILE
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) {
return itemStream.collect(groupingBy(Item::getUuid, Function.identity()));
}
我错过了什么?
答案 0 :(得分:11)
使用Collectors#toMap(Function, Function)
,生成每个Item
uuid
和Item
的密钥作为值本身。
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) {
return itemStream.collect(Collectors.toMap(Item::getUuid, Function.identity()));
}
来自javadoc的注释
如果映射的密钥包含重复项(根据
Object.equals(Object)
),当IllegalStateException
时抛出toMap(Function, Function, BinaryOperator)
执行收集操作。如果映射的键可能有 重复,改为使用try{}
。
答案 1 :(得分:1)
import requests
from bs4 import BeautifulSoup
import csv
import re
import time
import logging
try:
def parse_page(data):
'#Sleep to avoid excessive requests'
time.sleep(1)
subsoup = BeautifulSoup(data,"html.parser")
rs = requests.get("http://www.bbc.co.uk/sport/0/football/31776459")
ssubsoup = BeautifulSoup(rs.content,"html.parser")
matchoverview = subsoup.find('div', attrs={'id':'match-overview'})
print '--------------'
date = subsoup.find('div', attrs={'id':'article-sidebar'}).findNext('span').text
league = subsoup.find('a', attrs={'class':'secondary-nav__link'}).findNext('span').findNext('span').text
#HomeTeam info printing
homeTeam = matchoverview.find('div', attrs={'class':'team-match-details'}).findNext('span').findNext('a').text
homeScore = matchoverview.find('div', attrs={'class':'team-match-details'}).findNext('span').findNext('span').text
homeGoalScorers = []
for goals in matchoverview.find('div', attrs={'class':'team-match-details'}).findNext('p').find_all('span'):
homeGoalScorers.append(goals.text.replace(u'\u2032', "'"))
homeGoals = homeGoalScorers
homeGoals2 = ''.join(homeGoals)
homeGoals3 = re.sub("[^0-9']","",homeGoals2)
homeGoals4 = homeGoals3.replace("'","',")
homeGoals5 = homeGoals4.replace("'","H")
if homeScore == '0':
homeGoals5 =''
#AwayTeam info printing
awayTeam = matchoverview.find('div', attrs={'id': 'away-team'}).find('div', attrs={'class':'team-match-details'}).findNext('span').findNext('a').text
awayScore = matchoverview.find('div', attrs={'id': 'away-team'}).find('div', attrs={'class':'team-match-details'}).findNext('span').findNext('span').text
awayGoalScorers = []
for goals in matchoverview.find('div', attrs={'id': 'away-team'}).find('div', attrs={'class':'team-match-details'}).findNext('p').find_all('span'):
awayGoalScorers.append(goals.text.replace(u'\u2032', "'"))
awayGoals = awayGoalScorers
awayGoals2 = ''.join(awayGoals)
awayGoals3 = re.sub("[^0-9']","",awayGoals2)
awayGoals4 = awayGoals3.replace("'","',")
awayGoals5 = awayGoals4.replace("'","A")
if awayScore == '0':
awayGoals5 =''
#combine scores
scores = homeGoals5+awayGoals5
#Printouts
print date
print league
print '{0} {1} - {2} {3}'.format(homeTeam, homeScore, awayTeam, awayScore)
print scores
if len(homeTeam) >1:
with open('score.txt', 'a') as f:
writer = csv.writer(f)
writer.writerow([league,date,homeTeam,awayTeam,scores])
except:
print "Item Missing"
with open('score.txt', 'a') as f:
writer = csv.writer(f)
writer.writerow(["--Item Missing--"])
pass
def all_league_results():
r = requests.get("http://www.bbc.co.uk/sport/football/league-two/results")
soup = BeautifulSoup(r.content,"html.parser")
# Save Teams
for link in soup.find_all("a", attrs={'class': 'report'}):
fullLink = 'http://www.bbc.com' + link['href']
time.sleep(2)
subr = requests.get(fullLink)
logging.basicConfig(filename='LogReport.log',level=logging.DEBUG)
logging.debug('DEBUG ERROR:')
logging.info('INFO ERROR:')
logging.warning('WARNING ERROR:')
logging.error('ERROR WARNING:')
logging.critical('CRITICAL ERROR:')
parse_page(subr.text)
def specific_game_results(url):
subr = requests.get(url)
parse_page(subr.text)
#get specific games results
#specific_game_results('http://www.bbc.co.uk/sport/0/football/31776459')
#get all current league results
all_league_results()
通过密钥收集项目(复数,groupingBy()
)。
您想要List
:
toMap()
答案 2 :(得分:-1)
也许试试
itemStream.stream().collect(toMap(Item::getUuid,Functions.identity());